使用 pandas (python) 在两列之间进行垂直查找
Vertical lookup between two columns with pandas (python)
我想知道是否可以完成以下table以获得预期的结果(向右)
X Y X Y
–––––––––––––––-–- –––––––––––––––-–-
Argentina AR Argentina AR
Brazil NaN Brazil BR
Brazil BR Brazil BR
Canada CA Canada CA
NaN AR Argentina AR
Canada NaN Canada CA
我的意图是通过考虑来自 X 和 Y 列的信息来替换 NaN,特别是为了获得具有副本 country/code 的实例。每个国家只有一个代码,反之亦然。
import pandas as pd
import math
data = {
'X': ['A', 'B', 'B', 'C', None, 'C', 'C'],
'Y': [1, None, 2, 3, 1, None, 3]
}
df = pd.DataFrame(data)
df_d = df.dropna().drop_duplicates()
for i, val in df.iterrows():
if pd.isnull(val['X']):
df.loc[i, 'X'] = df_d.loc[df_d['Y'] == val['Y'], 'X'].values
if pd.isnull(val['Y']):
df.loc[i, 'Y'] = df_d.loc[df_d['X'] == val['X'], 'Y'].values
print(df)
首先,我复制了原始数据帧,删除了 NaN
值和重复项,只是为了获得唯一行以获取其值。然后遍历原始数据帧中的行并检查其是否 NaN
,如果是,则从唯一数据帧中获取值。
X Y
0 A 1.0
1 B 2.0
2 B 2.0
3 C 3.0
4 A 1.0
5 C 3.0
6 C 3.0
编辑
- 使用
.transform()
的原始答案会因旧而失效
pandas
的版本(例如 1.1.3
)。
- 有些情况下有人想根据
Y
填充缺失的 X
值,有些情况则相反。
- 一个更简单的方法是只得到一个唯一的映射
X: Y
。
def first_valid(g):
return g.bfill().iloc[0]
m = df.groupby('X')['Y'].apply(first_valid)
>>> m
X
Argentina AR
Brazil BR
Canada CA
Name: Y, dtype: object
如果你愿意,你可以把原来的缺失值补上df
,例如如果你有一个更大的 df
和其他列并且想要保持相同的形状,只需填充缺失值:
dct = df.groupby('X')['Y'].apply(first_valid).to_dict()
new_df = df.assign(
X=df['X'].fillna(df['Y'].map({v:k for k, v in dct.items()})),
Y=df['Y'].fillna(df['X'].map(dct)),
)
我想知道是否可以完成以下table以获得预期的结果(向右)
X Y X Y
–––––––––––––––-–- –––––––––––––––-–-
Argentina AR Argentina AR
Brazil NaN Brazil BR
Brazil BR Brazil BR
Canada CA Canada CA
NaN AR Argentina AR
Canada NaN Canada CA
我的意图是通过考虑来自 X 和 Y 列的信息来替换 NaN,特别是为了获得具有副本 country/code 的实例。每个国家只有一个代码,反之亦然。
import pandas as pd
import math
data = {
'X': ['A', 'B', 'B', 'C', None, 'C', 'C'],
'Y': [1, None, 2, 3, 1, None, 3]
}
df = pd.DataFrame(data)
df_d = df.dropna().drop_duplicates()
for i, val in df.iterrows():
if pd.isnull(val['X']):
df.loc[i, 'X'] = df_d.loc[df_d['Y'] == val['Y'], 'X'].values
if pd.isnull(val['Y']):
df.loc[i, 'Y'] = df_d.loc[df_d['X'] == val['X'], 'Y'].values
print(df)
首先,我复制了原始数据帧,删除了 NaN
值和重复项,只是为了获得唯一行以获取其值。然后遍历原始数据帧中的行并检查其是否 NaN
,如果是,则从唯一数据帧中获取值。
X Y
0 A 1.0
1 B 2.0
2 B 2.0
3 C 3.0
4 A 1.0
5 C 3.0
6 C 3.0
编辑
- 使用
.transform()
的原始答案会因旧而失效pandas
的版本(例如1.1.3
)。 - 有些情况下有人想根据
Y
填充缺失的X
值,有些情况则相反。 - 一个更简单的方法是只得到一个唯一的映射
X: Y
。
def first_valid(g):
return g.bfill().iloc[0]
m = df.groupby('X')['Y'].apply(first_valid)
>>> m
X
Argentina AR
Brazil BR
Canada CA
Name: Y, dtype: object
如果你愿意,你可以把原来的缺失值补上df
,例如如果你有一个更大的 df
和其他列并且想要保持相同的形状,只需填充缺失值:
dct = df.groupby('X')['Y'].apply(first_valid).to_dict()
new_df = df.assign(
X=df['X'].fillna(df['Y'].map({v:k for k, v in dct.items()})),
Y=df['Y'].fillna(df['X'].map(dct)),
)