簡體   English   中英

根據條件將值從一個pandas數據幀替換為另一個pandas數據幀

[英]Substitute values from one pandas data frame to another based on condition

我有兩個包含多列的數據框。

df_1 = pd.DataFrame({'A': ['x', '-', 'z'], 'B': [1, 6, 9], 'C': [2, 1, '-']})
> df_1

   A  B  C
0  x  1  2
1  -  6  1
2  z  9  -

df_2 = pd.DataFrame({'A': ['w', 'y', 'y'], 'B': [5, 6, 9], 'C': [2, 1, 8]})
> df_2

   A  B  C
0  w  5  2
1  y  6  1
2  y  9  8

如何根據條件(布爾掩碼)將一個數據幀中的值替換為另一個數據幀中的值? 這里,缺少值標記為'-' ,我想使用df_2值來獲取結果:

> df
   A  B  C
0  x  1  2
1  y  6  1
2  z  9  8   

IIUC你可以創建boolean mask ,通過astype將值轉換為string ,然后與-進行比較。 最后填充值隨-從另一個DataFramemaskwhere有反轉mask~

mask = df_1.astype(str) == '-'
print (mask)
       A      B      C
0  False  False  False
1   True  False  False
2  False  False   True

print (df_1.mask(mask, df_2))
   A  B  C
0  x  1  2
1  y  6  1
2  z  9  8

print (df_1.where(~mask, df_2))
   A  B  C
0  x  1  2
1  y  6  1
2  z  9  8

編輯評論:

一個可能的解決方案是su79eu7k ,謝謝:

masks = [('A', r'[a-zA-Z]'), ('B', r'\d'), ('C', r'\d')]; 
print pd.concat([~(df_1[col].astype(str).str.contains(regex)) for col, regex in masks], axis=1)

另一種解決方案是創建mask - 首先fillna可能的NaN值,然后replace錯過的值從dict replaceNaN並最后找到isnull值。

import pandas as pd
import numpy as np

df_1 = pd.DataFrame({'A': ['-x', '-', np.nan],'B': [1, 6, 'Unknown'],'C': [2, 1, 'Missing']})
print (df_1)

df_2 = pd.DataFrame({'A': ['w', 'y', 'y'], 'B': [5, 6, 9], 'C': [2, 1, 8]})
print (df_2)

mask_li = ['-','Unknown','Missing']  
d = {x:np.nan for x in mask_li}  

mask = df_1.fillna(1).replace(d).isnull()
print (mask)
       A      B      C
0  False  False  False
1   True  False  False
2  False   True   True

print (df_1.mask(mask, df_2))    
     A  B  C
0   -x  1  2
1    y  6  1
2  NaN  9  8

您可以使用str.contains ,但其他數據不能包含mask_li列表中的mask_li

mask_li = ['-','Unknown','Missing']    

mask= df_1.copy()
for col in df_1.columns:
    mask[col] = mask[col].astype(str).str.contains('|'.join(mask_li))

print (mask)
       A      B      C
0  False  False  False
1   True  False  False
2  False   True   True

print (df_1.mask(mask, df_2))    
   A  B  C
0  x  1  2
1  y  6  1
2  z  9  8

但是如果另一個數據包含來自mask_li值,則可能存在問題,例如-

例如:

import pandas as pd
import numpy as np

df_1 = pd.DataFrame({'A': ['-x', '-', '-z'], 'B': [1, 6, 'Unknown'], 'C': [2, 1, 'Missing']})
print (df_1)

df_2 = pd.DataFrame({'A': ['w', 'y', 'y'], 'B': [5, 6, 9], 'C': [2, 1, 8]})
print (df_2)

mask_li = ['-','Unknown','Missing']    

mask= df_1.copy()
for col in df_1.columns:
    mask[col] = mask[col].astype(str).str.contains('|'.join(mask_li))

print (mask)
      A      B      C
0  True  False  False
1  True  False  False
2  True   True   True

print (df_1.mask(mask, df_2))    
   A  B  C
0  w  1  2
1  y  6  1
2  y  9  8

一種可能的方案:

import pandas as pd
import numpy as np

df_1 = pd.DataFrame({'A': ['-x', '-', '-z'], 'B': [1, 6, 'Unknown'], 'C': [2, 1, 'Missing']})
print (df_1)

df_2 = pd.DataFrame({'A': ['w', 'y', 'y'], 'B': [5, 6, 9], 'C': [2, 1, 8]})
print (df_2)

mask_li = ['Unknown','Missing']    

mask= df_1.copy()
for col in df_1.columns:
    column = mask[col].astype(str)
    mask[col] = (column.str.contains('|'.join(mask_li))) | (column == '-')

print (mask)
       A      B      C
0  False  False  False
1   True  False  False
2  False   True   True

print (df_1.mask(mask, df_2))    
    A  B  C
0  -x  1  2
1   y  6  1
2  -z  9  8

暫無
暫無

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

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