我知道這個問題起初可能看起來是重復的,但事實是它不是,因為我找不到另一個答案或類似問題的解決方案適合我。
我正在使用pandas資料框,使用Python語言。
假設我們有 3 個資料集,A B和C。
- B和C是A的子資料集(資料幀A根據二進制列值分成兩部分)
- 資料集的長度不同(A最大,B和C較小,因為它們是A的子資料集)
- 每個資料集有 5 列:a、b、c、d和e(它們具有相同的列名)
- 列a、b、c和d(全部放在一起)沒有任何重復(它們可能是資料庫的組合鍵)
- 每個資料集的e列不同
- 每個資料集都有與其他資料集不同的索引(它們不是使用 pandas.loc 生成的,我正在處理它們“已經從 python 外部構建和獲取”)
我的問題是:如何在不丟失任何行的情況下將所有這些放在一起,并且在不使用索引的情況下正確配對它們?
這是一個例子:
* Content of A *:
a b c d e
"x" "y" 0 1 0.99 # 0
"x" "y" 1 1 0.43 # 1
"x" "z" 0 0 0.90 # 2
"y" "z" 0 1 0.11 # 3
"x" "z" 0 1 0.78 # 4
* Content of B *:
a b c d e
"x" "y" 0 1 0.12 # 0 of dataframe A
"x" "z" 0 0 0.01 # 2 of dataframe A
"y" "z" 0 1 0.45 # 3 of dataframe A
* Content of C *:
a b c d e
"x" "y" 1 1 0.06 # 1 of dataframe A
"x" "z" 0 0 0.65 # 2 of dataframe A
"x" "z" 0 1 0.20 # 4 of dataframe A
我想獲得這個輸出:
* Content of new_df *:
a b c d e_A e_B e_C
"x" "y" 0 1 0.99 0.12 NaN
"x" "y" 1 1 0.43 NaN 0.06
"x" "z" 0 0 0.90 0.01 0.65
"y" "z" 0 1 0.11 0.45 NaN
"x" "z" 0 1 0.78 NaN 0.20
我對代碼的第一次試用是以下行,但它洗掉了不包含所有三個值的行(相反,我需要插入 NaN)。
new_df1 = pd.merge(A, B, how='left', left_on=["a", "b", "c", "d"]
new_df2 = pd.merge(new_df1, C, how='left', left_on=["a", "b", "c", "d"]
如何實作獲得由所有列 (5) 和所有行組成的完整資料集的目標(A包含最大數量的行)?
可重現的輸入:
A = pd.DataFrame({'a': ['x', 'x', 'x', 'y', 'x'],
'b': ['y', 'y', 'z', 'z', 'z'],
'c': [0, 1, 0, 0, 0],
'd': [1, 1, 0, 1, 1],
'e': [0.99, 0.43, 0.9, 0.11, 0.78]})
B = pd.DataFrame({'a': ['x', 'x', 'y'],
'b': ['y', 'z', 'z'],
'c': [0, 0, 0],
'd': [1, 0, 1],
'e': [0.12, 0.01, 0.45]})
C = pd.DataFrame({'a': ['x', 'x', 'x'],
'b': ['y', 'z', 'z'],
'c': [1, 0, 0],
'd': [1, 0, 1],
'e': [0.06, 0.65, 0.2]})
uj5u.com熱心網友回復:
這似乎對我有用。
import pandas as pd
a = pd.read_csv('a.csv')
b = pd.read_csv('b.csv')
c = pd.read_csv('c.csv')
e = a.merge(b, how='left', left_on=['a', 'b', 'c', 'd'], right_on=['a','b','c', 'd'], suffixes=['_A', '_B'])
e = e.merge(c, how='left', left_on=['a', 'b', 'c', 'd'], right_on=['a','b','c', 'd'])
e = e.rename(columns={'e': 'e_C'})
print(e.head())
稍微解釋一下,pd.DataFrame.merge()目前支持顯式宣告加入列doc。所以使用它我們可以合并它。
并且 suffix 引數允許您通過為兩個 df 添加提供的后綴來重命名重疊列(left_df_suffix, right_df_suffix)。
休息就像你試過的那樣。合并后我重命名了(或DF)的e列。c.csv希望這可以幫助。
uj5u.com熱心網友回復:
組合字串中常見的鍵,如下面的代碼所示。
A['pKey'] = A.apply(lambda row: row['a'] "_" row['b'] "_" str(row['c']) "_" str(row['d']), axis=1)
B['pKey'] = B.apply(lambda row: row['a'] "_" row['b'] "_" str(row['c']) "_" str(row['d']), axis=1)
C['pKey'] = C.apply(lambda row: row['a'] "_" row['b'] "_" str(row['c']) "_" str(row['d']), axis=1)
然后使用這個新列組合表:
merge_ab = A.merge(B, on='pKey', how='left', suffixes=('_A', '_B'))
merge_abc = merge_ab.merge(C, on='pKey', how='left', suffixes=('', '_C'))
現在洗掉無用的列。
a b c d e_A e_B e_C
0 x y 0 1 0.99 0.12 NaN
1 x y 1 1 0.43 NaN 0.06
2 x z 0 0 0.93 0.01 0.65
3 y z 0 1 0.11 0.45 NaN
4 x z 0 1 0.78 NaN 0.20
uj5u.com熱心網友回復:
您可以使用字典來保存資料框并使用functools.reduce:
dfs = {'A': A, 'B': B, 'C': C}
from functools import reduce
out= reduce(lambda a, b: a.merge(b, how='left', on=["a", "b", "c", "d"]),
[d.rename(columns={'e': f'e_{k}'}) for k,d in dfs.items()])
或者,如果您有“e”以外的非合并列:
dfs = {'A': A, 'B': B, 'C': C}
from functools import reduce
out = (reduce(lambda a, b: a.join(b, how='left'),
[d.set_index(["a", "b", "c", "d"]).add_suffix(f'_{k}')
for k,d in dfs.items()])
.reset_index()
)
輸出:
a b c d e_A e_B e_C
0 x y 0 1 0.99 0.12 NaN
1 x y 1 1 0.43 NaN 0.06
2 x z 0 0 0.90 0.01 0.65
3 y z 0 1 0.11 0.45 NaN
4 x z 0 1 0.78 NaN 0.20
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/460340.html
上一篇:BigQuery中的非重復值
