我有两个数据框。
df1
col1 var1 var2 var3
X11 NA (for var3)
X12 NA (for var2)
X13 NA (for var1)
df1 有几列(代表某些类别的 float64 类型),例如 var1、var2、var3,每个列的值在 1-5 之间,并且类别有一些缺失值。
我想使用另一个数据框 df2 填充缺失值(在 var1、var2 和 var3 列中),这样 df2 有一列包含该类别的值。
df2
col1 col2 val col4
X11 var1 3 X11-X21
X12 var3 2 X21-X22
X13 var2 1 X13-X32
col4 是 col1 和 col2 的串联,但没有多大帮助。
我怎样才能做到这一点? 由于我们需要查找几列,并且由于 df1 的结构,我发现使用pivot或melt甚至one-hot编码(生成5列,每列都带有_1到_5后缀)很复杂。 我也想过创建一个集合,但这些对必须是唯一的,但事实并非如此。 当我想到使用字典时也是如此,因为我无法想到唯一的键。
我该如何解决这个问题?
谢谢。
下面的示例适用于您提供的小样本。
代码遍历
df1
的行,将每一行读出到变量 row
中。然后它会遍历 row
的值(和列名称)。当值为 pd.NA
时,它会根据 df2
的索引索引到 row
,并返回该索引处的 df2["val"]
。
import pandas as pd
#
# Create test data
#
df1 = pd.DataFrame({
'col1': ['X11', 'X12', 'X13'],
'var1': [100, 200, pd.NA],
'var2': [300, pd.NA, 400],
'var3': [pd.NA, 500, 600]
})
df2 = pd.DataFrame({
'col1': ['X11', 'X12', 'X13'],
'col2': ['var3', 'var2', 'var1'],
'val': [3, 2, 1],
})
#
# Solution
#
def fill_missing(row):
idx = row.name #index of current row
#Go over each entry in this row
for col, value in row.items():
if not pd.isna(value):
continue
#If NA, cross reference against df2
# and overwrite the row's value
col_to_fill = df2.loc[idx, 'col2']
assert col_to_fill == col #should match if df2 is right about the NA locations
val_to_fill = df2.loc[idx, 'val']
row[col] = val_to_fill
return row
# Apply the fill_missing function to each row in df1 using .apply(..., axis=1)
df1_filled = df1.copy().apply(fill_missing, axis=1)