簡體   English   中英

在兩列替代解決方案上合並數據框

[英]Merging dataframes on two columns alternative solution

我一直在嘗試為以下代碼找到替代(可能更優雅)的解決方案,但沒有任何運氣。 這是我的代碼:

import os
import pandas as pd

os.chdir(os.getcwd())

df1 = pd.DataFrame({'Month': [1]*6 + [13]*6,
                   'Temp': [0, 1, 2, 3, 4, 5]*2,
                    'Place': [12, 53, 6, 11, 9, 10, 0, 0, 0, 0, 0, 0],
                    'Place2': [1, 0, 23, 14, 9, 8, 0, 0, 0, 0, 0, 0],
                    'Place3': [2, 64, 24, 66, 14, 21, 0, 0, 0, 0, 0, 0]}
                   )

df2 = pd.DataFrame({'Month': [13] * 6,
                   'Temp': [0, 1, 2, 3, 4, 5],
                    'Place': [1, 22, 333, 444, 55, 6]})

# Here it creates new columns "Place_y" and "Place_x".
# I want to avoid this if possible.
df_merge = pd.merge(df1, df2, how='left',
                  left_on=['Temp', 'Month'],
                  right_on=['Temp', 'Month'])

df_merge.fillna(0, inplace=True)

add_not_nan = lambda x: x['Place_x'] if pd.isnull(x['Place_y']) else x['Place_y']

df_merge['Place'] = df_merge.apply(add_not_nan, axis=1)

df_merge.drop(['Place_x', 'Place_y'], axis=1, inplace=True)

print(df_merge)

我想要完成的是基於“Month”和“Temp”列合並兩個數據框,同時為缺失值保留 0。 我想知道是否有任何方法可以在不創建 _x 和 _y 列的情況下合並數據幀(基本上是一種跳過創建和刪除這些列的方法)。

輸入:

  • 第一個數據框
    Month  Temp  Place  Place2  Place3
0       1     0     12       1       2
1       1     1     53       0      64
2       1     2      6      23      24
3       1     3     11      14      66
4       1     4      9       9      14
5       1     5     10       8      21
6      13     0      0       0       0
7      13     1      0       0       0
8      13     2      0       0       0
9      13     3      0       0       0
10     13     4      0       0       0
11     13     5      0       0       0 
  • 第二個數據框
   Month  Temp  Place
0     13     0      1
1     13     1     22
2     13     2    333
3     13     3    444
4     13     4     55
5     13     5      6

輸出:

  • 合並后
    Month  Temp  Place_x  Place2  Place3  Place_y
0       1     0       12       1       2      NaN
1       1     1       53       0      64      NaN
2       1     2        6      23      24      NaN
3       1     3       11      14      66      NaN
4       1     4        9       9      14      NaN
5       1     5       10       8      21      NaN
6      13     0        0       0       0      1.0
7      13     1        0       0       0     22.0
8      13     2        0       0       0    333.0
9      13     3        0       0       0    444.0
10     13     4        0       0       0     55.0
11     13     5        0       0       0      6.0
  • 最終(期望)
    Month  Temp  Place2  Place3  Place
0       1     0       1       2    0.0
1       1     1       0      64    0.0
2       1     2      23      24    0.0
3       1     3      14      66    0.0
4       1     4       9      14    0.0
5       1     5       8      21    0.0
6      13     0       0       0    1.0
7      13     1       0       0   22.0
8      13     2       0       0  333.0
9      13     3       0       0  444.0
10     13     4       0       0   55.0
11     13     5       0       0    6.0

似乎您不需要df1 Place列,您可以在合並之前將其刪除:

(df1.drop('Place', axis=1)
    .merge(df2, how='left', on=['Temp', 'Month'])
    .fillna({'Place': 0}))

#    Month  Temp  Place2  Place3  Place
#0       1     0       1       2    0.0
#1       1     1       0      64    0.0
#2       1     2      23      24    0.0
#3       1     3      14      66    0.0
#4       1     4       9      14    0.0
#5       1     5       8      21    0.0
#6      13     0       0       0    1.0
#7      13     1       0       0   22.0
#8      13     2       0       0  333.0
#9      13     3       0       0  444.0
#10     13     4       0       0   55.0
#11     13     5       0       0    6.0

如果您不知道有多少這樣的列,並且如果您總是想將第二個數據框中的列包含在您不用作關鍵列的重疊列名稱中,那么您可以使用pd.merge后綴參數屏蔽這些變量pd.merge然后使用pandas.DataFrame.filter過濾掉pandas.DataFrame.filter屏蔽字符的列:

df1.merge(df2,
          how='left', 
          left_on=['Temp', 'Month'],
          right_on=['Temp', 'Month'],
          suffixes=('##@', '')).fillna(0).filter(regex='.*(?<!##@)$')      

輸出:

    Month  Temp  Place2  Place3  Place
0       1     0       1       2    0.0
1       1     1       0      64    0.0
2       1     2      23      24    0.0
3       1     3      14      66    0.0
4       1     4       9      14    0.0
5       1     5       8      21    0.0
6      13     0       0       0    1.0
7      13     1       0       0   22.0
8      13     2       0       0  333.0
9      13     3       0       0  444.0
10     13     4       0       0   55.0
11     13     5       0       0    6.0

顯然,您還可以在合並之前通過檢查第一個數據幀中第二個數據幀的列是否存在來過濾掉開始時的列:

cols=[col for col in df1.columns if col in ('Temp', 'Month') or col not in df2.columns ]
df1[cols].merge(df2, how='left', 
          left_on=['Temp', 'Month'],
          right_on=['Temp', 'Month']).fillna(0)

    Month  Temp  Place2  Place3  Place
0       1     0       1       2    0.0
1       1     1       0      64    0.0
2       1     2      23      24    0.0
3       1     3      14      66    0.0
4       1     4       9      14    0.0
5       1     5       8      21    0.0
6      13     0       0       0    1.0
7      13     1       0       0   22.0
8      13     2       0       0  333.0
9      13     3       0       0  444.0
10     13     4       0       0   55.0
11     13     5       0       0    6.0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM