繁体   English   中英

将具有不同列的多个数据帧合并在一起,除了 5

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM