【Python】chunksize分块读取 *[list] isinstance(a, str)

本文介绍如何处理2019-2020年间的大规模Covid-19数据,通过分块读取优化效率,对日期进行特殊拆分以方便按年月日分析,并利用isinstance()函数检查数据类型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、场景需求

2019-2020年Covid-19数据,20多万行,提取一部分数据,以便进一步做可视化分析。
在这里插入图片描述

二、技术重点

2.1 数据分块读取

一般数据超过5万行,就建议分块读取,可以减轻系统压力,提高数据处理效率。
这次的20多万行,其实一次性读入也行,就是有点吃力,但如果是2000万行、20亿行呢?那就必须分块了。稍微有点规模的数据库上亿的数据量都是很正常的。
Pandas分块读取的逻辑比较简单:

  1. 首先创建一个指定行数的分块文本读取器,并不真正读取数据
chunks = pd.read_csv("../data/covid-19.csv", chunksize=10000)
  1. 循环分块读取,每次读取指定行,得到一个DataFrame,进行业务逻辑处理,直至文件全部读完
for i, df in enumerate(chunks):
    print(f'正在处理第 {i} 个 chunk')
    ...

2.2 对日期分列,以便按年月日分别可视化

常规对日期分列就是 data.split(’-’),得到一个列表 [年,月,日]

print(a.split("-"))         # ['2019', '12', '01']

本次采取了一个特殊的技巧,就是前面加了一个星号*

print(*a.split("-"))        # 2019 12 01
  1. 列表、元组前面加一个星号,作用是将列表元素解开(unpacke)成多个独立的参数,传入函数。
def add(a, b):
    return a + b

data = [7, 8]
print(add(*data)) # 15
import numpy as np
print(np.arange(3,6)) # [3 4 5]

list2 = [3, 6]
print(np.arange(*list2)) # [3 4 5]
  1. 字典前面加两个星号,是将字典解开成独立的元素作为形参,特别注意字典的key要与函数形参的变量名一致。
def add(a, b):
    return a + b

data = {'a':7, 'b':8}
print(add(**data)) # 15
# 等同于
print(add(a=7, b=8))

2.3 isinstance(a, str) 判断数据类型

isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。
isinstance() 与 type() 区别:

  • type() 不会认为子类是一种父类类型,不考虑继承关系。
  • isinstance() 会认为子类是一种父类类型,考虑继承关系。
    如果要判断两个类型是否相同推荐使用 isinstance(),语法为:isinstance(object, classinfo)

三、完整代码

import pandas as pd
import os
import datetime
"""
知识点:
3. chunksize 分块
4. *[list] 分列
5. isinstance(a, str) 判断类型
"""
# 分块
chunks = pd.read_csv("../data/covid-19.csv", chunksize=10000)   # 生成一个文本读取器,并没有真正去读文件

total = 0
file = "../data/result_分块分列.csv"
if os.path.exists(file):
    os.remove(file)

for i, df in enumerate(chunks):
    print(f'正在处理第 {i} 个 chunk')
    # 处理空值:删除全为空值的列
    df.dropna(how="all", inplace=True, axis=1)
    result = []
    df = df[['date', 'country', 'countryCode', 'confirmed']]
    for a, b, c, d in df.values:
        if not isinstance(a, str):  # 如果data不是str类型,就抛弃本行数据
            continue
        # 提取指定年月的数据
        if a.split("-")[0] == '2020' and 2 <= int(a.split("-")[1]) <= 3:
            result.append((*a.split("-"), b, d))      # 结果为 [()],元组列表常用
            # result.append(a.split("-")+[b, d])          # 结果为 [[]],二维列表不常用
            total += 1

    print(f'累计获取符合条件的 {total} 条数据')
    df = pd.DataFrame(result, columns=["年", "月", "日", "国家", "数量"])
    df.to_csv(file, index=False, mode='a', header=not os.path.exists(file), encoding="utf-8")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岳涛@泰山医院

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值