使用 pandas/dask Python 操作大型 .csv 文件
Operating large .csv file with pandas/dask Python
我有一个来自英国土地登记处的大型 .csv 文件 (5GB)。我需要找到所有 bought/sold 两次或更多次的房地产。
table 的每一行如下所示:
{F887F88E-7D15-4415-804E-52EAC2F10958},"70000","1995-07-07 00:00","MK15 9HP","D","N","F","31","","ALDRICH DRIVE","WILLEN","MILTON KEYNES","MILTON KEYNES","MILTON KEYNES","A","A"
我从未使用过 pandas 或任何数据科学库。到目前为止,我已经想出了这个计划:
加载 .csv 文件并添加 headers 和列名称
删除不必要的列
创建已编辑 df 的 hashmap 并查找重复项
将重复项导出到新的 .csv 文件
根据我的研究,我发现 pandas 对非常大的文件不好,所以我使用了 dask
df = dd.read_csv('pp-complete.csv', header=None, dtype={7: 'object', 8: 'object'}).astype(str)
df.columns = ['ID', 'Price', 'Date', 'ZIP', 'PropType', 'Old/new', 'Duration', 'Padress', 'Sadress', 'Str', 'Locality', 'Town', 'District', 'County', 'PPDType', 'Rec_Stat']
df.head()
- 在我尝试删除不需要的列之后
df.drop('ID', axis=1).head()
也试过
indexes_to_remove = [0, 1, 2, 3, 4, 5, 6, 7, 14, 15, 16]
for index in indexes_to_remove:
df.drop(df.index[index], axis=1)
没有任何效果。
任务是显示已经bought/sold两次或更多次的属性。我决定只使用地址列,因为其他列的数据不一致(ID - 是唯一的交易代码、日期、报价类型等)
我需要用最少的内存和 CPU 的使用率来完成这个任务,这就是我使用 hashmap 的原因。
我不知道是否有其他方法可以更轻松或更有效地做到这一点。
一些小建议:
如果 5GB 是完整数据集,最好使用普通 pandas。您概述的策略可能涉及跨分区的通信,因此它在计算上会更加昂贵(或者需要一些工作来提高效率)。使用 pandas
所有数据都将在内存中,因此 sorting/duplication 检查会很快。
在代码中,确保分配修改后的数据帧。通常分配修改以替换现有数据框:
# without "df = " part, the modification is not stored
df = df.drop(columns=['ID'])
- 如果内存是一个很大的限制,那么请考虑仅加载您需要的数据(而不是加载所有内容然后删除特定列)。为此,我们需要向
pd.read_csv
的 usecols
kwarg 提供列列表。这是粗略的想法:
column_names = ['ID', 'Price', 'Date', 'ZIP', 'PropType', 'Old/new', 'Duration', 'Padress', 'Sadress', 'Str', 'Locality', 'Town', 'District', 'County', 'PPDType', 'Rec_Stat']
indexes_to_remove = [0, 1, 2, 3, 4, 5, 6, 7, 14, 15, 16]
indexes_to_keep = [i for i in range(len(column_names)) if i not in indexes_to_remove]
column_names_to_keep = [n for i,n in enumerate(column_names) if i in indexes_to_keep]
df = pd.read_csv('some_file.csv', header=column_names_to_keep, usecols=indexes_to_keep)
我有一个来自英国土地登记处的大型 .csv 文件 (5GB)。我需要找到所有 bought/sold 两次或更多次的房地产。
table 的每一行如下所示:
{F887F88E-7D15-4415-804E-52EAC2F10958},"70000","1995-07-07 00:00","MK15 9HP","D","N","F","31","","ALDRICH DRIVE","WILLEN","MILTON KEYNES","MILTON KEYNES","MILTON KEYNES","A","A"
我从未使用过 pandas 或任何数据科学库。到目前为止,我已经想出了这个计划:
加载 .csv 文件并添加 headers 和列名称
删除不必要的列
创建已编辑 df 的 hashmap 并查找重复项
将重复项导出到新的 .csv 文件
根据我的研究,我发现 pandas 对非常大的文件不好,所以我使用了 dask
df = dd.read_csv('pp-complete.csv', header=None, dtype={7: 'object', 8: 'object'}).astype(str)
df.columns = ['ID', 'Price', 'Date', 'ZIP', 'PropType', 'Old/new', 'Duration', 'Padress', 'Sadress', 'Str', 'Locality', 'Town', 'District', 'County', 'PPDType', 'Rec_Stat']
df.head()
- 在我尝试删除不需要的列之后
df.drop('ID', axis=1).head()
也试过
indexes_to_remove = [0, 1, 2, 3, 4, 5, 6, 7, 14, 15, 16]
for index in indexes_to_remove:
df.drop(df.index[index], axis=1)
没有任何效果。
任务是显示已经bought/sold两次或更多次的属性。我决定只使用地址列,因为其他列的数据不一致(ID - 是唯一的交易代码、日期、报价类型等)
我需要用最少的内存和 CPU 的使用率来完成这个任务,这就是我使用 hashmap 的原因。
我不知道是否有其他方法可以更轻松或更有效地做到这一点。
一些小建议:
如果 5GB 是完整数据集,最好使用普通 pandas。您概述的策略可能涉及跨分区的通信,因此它在计算上会更加昂贵(或者需要一些工作来提高效率)。使用
pandas
所有数据都将在内存中,因此 sorting/duplication 检查会很快。在代码中,确保分配修改后的数据帧。通常分配修改以替换现有数据框:
# without "df = " part, the modification is not stored
df = df.drop(columns=['ID'])
- 如果内存是一个很大的限制,那么请考虑仅加载您需要的数据(而不是加载所有内容然后删除特定列)。为此,我们需要向
pd.read_csv
的usecols
kwarg 提供列列表。这是粗略的想法:
column_names = ['ID', 'Price', 'Date', 'ZIP', 'PropType', 'Old/new', 'Duration', 'Padress', 'Sadress', 'Str', 'Locality', 'Town', 'District', 'County', 'PPDType', 'Rec_Stat']
indexes_to_remove = [0, 1, 2, 3, 4, 5, 6, 7, 14, 15, 16]
indexes_to_keep = [i for i in range(len(column_names)) if i not in indexes_to_remove]
column_names_to_keep = [n for i,n in enumerate(column_names) if i in indexes_to_keep]
df = pd.read_csv('some_file.csv', header=column_names_to_keep, usecols=indexes_to_keep)