Python Pandas-如果行包含相同的值,如何匹配行
我有一个数据框,有4列:“年龄1”、“姓名1”、“年龄2”和“姓名2”Python Pandas-如果行包含相同的值,如何匹配行,python,pandas,Python,Pandas,我有一个数据框,有4列:“年龄1”、“姓名1”、“年龄2”和“姓名2” df = pd.DataFrame(index=[0, 4, 6, 9], data={'age_1': [18, np.nan, 12, np.nan], 'name_1': ['Fred', np.nan, 'Harry', np.nan], 'age_2': [np.nan, 34, np
df = pd.DataFrame(index=[0, 4, 6, 9],
data={'age_1': [18, np.nan, 12, np.nan],
'name_1': ['Fred', np.nan, 'Harry', np.nan],
'age_2': [np.nan, 34, np.nan, 45],
'name_2': [np.nan, 'Jim', np.nan, 'Fred']})
输出
age_1 name_1 age_2 name_2
0 18.0 Fred NaN NaN
4 NaN NaN 34.0 Jim
6 12.0 Harry NaN NaN
9 NaN NaN 45.0 Fred
age_1 name_1 age_2 name_2
0 18.0 Fred 45.0 Fred
所有名称都出现两次,一次出现在名称_1中,一次出现在名称_2中。我想把名称_1和名称_2中具有相同项的行放在一起。例如,从上面的代码片段中,我希望它将第一行和最后一行放在一起,如下所示:
age_1 name_1 age_2 name_2
0 18.0 Fred 45.0 Fred
# check that there are no repeats
for col in ("name_1", "name_2"):
assert df[col].dropna().nunique() == df[col].dropna().shape[0]
# check that all `name_1`s have corresponding `name_2`s
assert set(df["name_1"].dropna()) == set(df["name_2"].dropna())
如果df是您的数据帧,则任何帮助都将非常有用:
df[["age_1", "name_1"]].dropna(how="all").join(df[["name_2", "age_2"]].dropna(how="all").set_index("name_2")[["age_2"]], on="name_1")
将为您提供大约您要查找的内容名称不会像您的示例中那样重复,因为它是正在连接的键,它只会出现一次
请注意,这是一个左连接,任何没有相应名称的名称都将被丢弃,但是没有相应名称的名称将保留,如Harry。如果要保留这些名称,只需将how=outer作为关键字参数添加到join方法中即可。如果你确定所有的名字都会出现两次,那就没关系了
如果名称_1有多个名称_2,则该行将重复以容纳尽可能多的名称_2。同样,如果每个名称在name_1列和name_2列中分别出现两次、一次和一次,这并不重要。我会添加一个这样的检查:
age_1 name_1 age_2 name_2
0 18.0 Fred 45.0 Fred
# check that there are no repeats
for col in ("name_1", "name_2"):
assert df[col].dropna().nunique() == df[col].dropna().shape[0]
# check that all `name_1`s have corresponding `name_2`s
assert set(df["name_1"].dropna()) == set(df["name_2"].dropna())
已编辑:要添加评论中建议的dropna,可以将数据框拆分为两部分,并使用“合并”将其连接起来。由于联接列name_1和name_2具有空值,因此必须先删除空值
l1 = ['age_1', 'name_1']
l2 = ['age_2', 'name_2']
df[l1].dropna().merge(df[l2].dropna(), left_on='name_1', right_on='name_2')
#outputs:
age_1 name_1 age_2 name_2
0 18.0 Fred 45.0 Fred
输出
age_1 name_1 age_2 name_2
0 18.0 Fred NaN NaN
4 NaN NaN 34.0 Jim
6 12.0 Harry NaN NaN
9 NaN NaN 45.0 Fred
age_1 name_1 age_2 name_2
0 18.0 Fred 45.0 Fred
如果一个名称出现两次以上怎么办?如果我向数据框中添加列,会发生什么情况?上面的代码是否需要更改?您应该在合并期间添加dropna,就像我所做的那样,或者在合并之后添加dropna。