[英]Merge two columns if their values are the same in a third column pandas
我有一個數據框(熊貓):
import pandas as pd
df = pd.DataFrame({'A': ['x1', 'x2', 'x3', 'x4'],
'B': ['b', 'b', 'c', 'c'],
'C': ['d', 'd', 'e', 'e'],
'D': ['x', 'y', 'y', 'x'],})
我想合並 A 中值唯一的所有列的值。
ouput = pd.DataFrame({'A': ['x1', 'x2', 'x3', 'x4'],
'BC': ['bd', 'bd', 'ce', 'ce'],
'D': ['x', 'y', 'y', 'x'],})
最好有一個獨立於列名 B、C 工作的解決方案(也許還有更多列具有這種“冗余信息”)。 A 的列名是已知的。
鑒於我的初始數據框是:
df = pd.DataFrame({'A': ['x1', 'x2', 'x3', 'x4'],
'B': ['b', 'b', 'c', 'c'],
'C': ['d', 'd', 'd', 'e'],
'D': ['x', 'y', 'y', 'x'],})
所需的輸出是初始 df(無變化):
df = pd.DataFrame({'A': ['x1', 'x2', 'x3', 'x4'],
'B': ['b', 'b', 'c', 'c'],
'C': ['d', 'd', 'd', 'e'],
'D': ['x', 'y', 'y', 'x'],})
非常感謝!
完整的解決方案(感謝比利時人羅比):
import pandas as pd
df = pd.DataFrame({'A': ['x1', 'x2', 'x3', 'x4'],
'B': ['b', 'b', 'c', 'c'],
'C': ['d', 'd', 'e', 'e'],
'D': ['x', 'y', 'y', 'x']})
print(df)
def is_redundant(df, A, B):
#remove column a
A=A
B=B
if len(df.groupby(f'{A}')) == len(df.groupby([f'{A}', f'{B}'])):
return True
else:
return False
def drop_redundant(df, redundant_groups):
list=redundant_groups
for i in list:
if len(df.groupby(f'{i[0]}')) == len(df.groupby([f'{i[0]}', f'{i[1]}'])):
df[f'{i[0]}' + f'{i[1]}'] = df[[f'{i[0]}', f'{i[1]}']].sum(axis=1)
df.drop([f'{i[0]}', f'{i[1]}'], axis=1, inplace=True)
return(df)
else:
return(df)
cols = [c for c in df.columns if c != 'A']
redundant_groups = []
idx_left = 0
while idx_left < len(cols)-1:
new_group = []
idx_right = idx_left+1
while idx_right < len(cols):
if is_redundant(df, cols[idx_left], cols[idx_right]):
new_group.append(cols.pop(idx_right))
else:
idx_right += 1
if new_group:
redundant_groups.append(new_group + [cols[idx_left]])
idx_left += 1
print(redundant_groups)
drop_redundant(df, redundant_groups)
print(df)
輸出:
A B C D
0 x1 b d x
1 x2 b d y
2 x3 c e y
3 x4 c e x
[['C', 'B']]
A D CB
0 x1 x db
1 x2 y db
2 x3 y ec
3 x4 x ec
[Finished in 0.837s]
要比較列'B'
和'C'
是否“冗余”:
len(df.groupby('B')) == len(df.groupby(['B', 'C'])
這將檢查將'C'
添加到分組標簽是否需要我們添加更多組,而'B'
僅按'B'
分組。
然后,您可以輕松地在df.columns
所有標簽對上運行它(確保不包含'A'
)。
如果發現兩列有冗余信息,可以使用:
df['B' + 'C'] = df[['B', 'C']].sum(axis=1)
df.drop(['B', 'C'], axis=1, inplace=True)
用組合信息替換它們。
如果您想在雙循環中使用它(檢查所有列對),您必須小心,因為您可能有 3 列都包含相同的信息(例如,B、C 和 F),並且處理完 B 和 C 后,您將嘗試比較 B 和 F——但 B 列不再存在。
為了解決這個問題,我可能首先嘗試構建一個所有冗余對的列表。 假設我們有一個“ is_redundant(df, c1, c2)
”函數(使用上面的行進行比較)。
cols = [c for c in df.columns if c != 'A']
redundant_groups = []
idx_left = 0
while idx_left < len(cols)-1:
new_group = []
idx_right = idx_left+1
while idx_right < len(cols):
if is_redundant(df, cols[idx_left], cols[idx_right]):
new_group.append(cols.pop(idx_right))
else:
idx_right += 1
if new_group:
redundant_groups.append(new_group + [cols[idx_left]])
idx_left += 1
這將創建所有相互冗余的列組。
之后,您可以輕松修改上述組合代碼以同時處理多個列。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.