[英]Merging multiple dataframes together that have different columns except 5
我将 1,424 个数据帧推入一个列表,如下所示:
import os
df = []
i = 0
for filename in os.listdir(output_path):
if filename.endswith(".csv"):
df.append(pd.read_csv(os.path.join(output_path, filename)))
else:
continue
我想将它们全部合并在一起。 这是我想仅使用 2 个 dfs 来模拟的示例:
df1 = pd.read_csv('../output/2009/census_data_2009_p1.csv')
df2 = pd.read_csv('../output/2009/census_data_2009_p2.csv')
df1 = df1.merge(df2, how = 'left', on = ['Location+Type', 'Year', 'state', 'Census_tract', 'County_name'])
除了 df 列表中的所有这些,我将如何做后者? 具体来说,我想使用'Location+Type', 'Year', 'state', 'Census_tract', 'County_name'
键对所有数据帧进行左连接
即使我有 64 GB 的 RAM,我目前也收到此错误。
The kernel appears to have died. It will restart automatically.
当我运行此代码时会发生这种情况:
from functools import reduce
df_merged = reduce(lambda l, r: pd.merge(l, r,
how='left',
on=['Location+Type',
'Year',
'state',
'Census_tract',
'County_name']), dfs)
或此代码
[
dfi.set_index(
["Location+Type", "Year", "state", "Census_tract", "County_name"], inplace=True
)
for dfi in df
]
df[0].join(df[1:], how="left")
尝试使用 set index 和 join:
[
dfi.set_index(
["Location+Type", "Year", "state", "Census_tract", "County_name"], inplace=True
)
for dfi in df
]
df[0].join(df[1:], how="left")
首先,在第一个代码块中进行一些清理:
import os
dfs = []
for filename in os.listdir(output_path):
if filename.endswith(".csv"):
dfs.append(pd.read_csv(os.path.join(output_path, filename)))
要将 DataFrame 列表合并为单个 DataFrame:
pd.concat(dfs, join='inner')
join='inner'
仅选择 DataFrame 列表中的公共列。
一个简短的演示:
df1 = pd.DataFrame(data=[[1,2,3], [2,3,1]], columns=['a', 'b', 'c'])
a b c
0 1 2 3
1 2 3 1
df2 = pd.DataFrame(data=[[1,2,3], [2,3,1]], columns=['b', 'c', 'd'])
b c d
0 1 2 3
1 2 3 1
pd.concat([df1, df2], join='inner')
b c
0 2 3
1 3 1
0 1 2
1 2 3
请注意结果索引。 如果需要,您可以使用reset_index()
来重置索引。
我相信最干净的选择之一是使用reduce
映射合并操作:
from functools import reduce
df_merged = reduce(lambda l, r: pd.merge(l, r,
how='left',
on=['Location+Type',
'Year',
'state',
'Census_tract',
'County_name']), df)
然而,这假设数据帧以所需的方式排序。
执行此操作的更内存有效的方法(但可以说不太干净)是简单地迭代数据帧:
df_merged = df[0].copy() # we use the initial dataframe to start
del df[0]
for _ in range(len(df)):
df_merged = df_merged.merge(df[0],
how='left',
on=['Location+Type',
'Year',
'state',
'Census_tract',
'County_name'])
# this will free up the contents of the recently merged dataframe
del df[0]
# For the columns in the variable
columns = ['Location+Type', 'Year', 'state', 'Census_tract', 'County_name']
# Set the indexes in order to join by index
for my_df in df:
my_df.set_index(columns)
# Join the dataframe
res_df = df[0]
for index in range(1, len(df)):
res_df.join(df[index], how='outer')
# Or if you only want to merge
pd.concat(df, join='outer')
首先,我会使用生成器来保存您机器的内存,执行时间可能会更长,但您的机器一次只能处理一个文件
import os
import pandas as pd
def census_dataframes():
for filename in os.listdir(output_path):
if filename.endswith(".csv"):
yield pd.read_csv(os.path.join(output_path, filename))
else:
continue
dataframes = census_dataframes()
#get first dataframe from generator
df1 = next(dataframes)
for frame in dataframes:
df1 = df1.merge(frame, how = 'left', on = ['Location+Type', 'Year', 'state', 'Census_tract', 'County_name'])
如果上述方法没有带来结果,请检查输出数据帧的大小。 为了有效使用,您至少需要比数据帧所需的内存多 2 倍。
可以通过在读取 csv 期间优化数据类型来进一步节省内存,例如
yield pd.read_csv(os.path.join(output_path, filename), dtype= {‘a’: np.float32, ‘b’: np.int32, ‘c’: ....})
如果您有经常在列中重复的文本条目(如“男人”、“女性”、“未公开”等),您可以将它们转换为类别并节省大量内存。 但是,要在大量文件上执行此操作需要事先准备和预先定义类别。
请参阅有关“分类数据”主题的熊猫文档
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.