簡體   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