![](/img/trans.png)
[英]how to iterate each row of one dataframe and compare with rows in another dataframe in Python?
[英]How to iterate a row and compare with each other?
例如,如果名称“Mark”重复,并且与包含“Mark”的其他行相比,“Age”值或“Gender”值不同,则必须删除此类列。
创建数据框的代码:
df = pd.DataFrame({'Name' : ['Mark', 'Mark', 'Mark', 'Mark', 'Mark', 'Nick', 'Nick', 'John', 'Sunny', 'Sunny'],
'Age' : ['22', '22', '25', '25', '17', '20', '20', '17', '23', '23'],
'Gender' : ['F', 'F', 'F', 'F', 'F', 'F', 'F', 'M', 'M', 'M']})
数据框如下:
Name Age Gender
0 Mark 22 F
1 Mark 22 F
2 Mark 25 F
3 Mark 25 F
4 Mark 17 F
5 Nick 20 F
6 Nick 20 F
7 John 17 M
8 Sunny 23 M
9 Sunny 23 M
预期的输出是:
Name Age Gender
0 Nick 20 F
1 Nick 20 F
2 John 17 M
3 Sunny 23 M
4 Sunny 23 M
例如在第 1 和第 2 行 Name 是 Mark,Age 是 22,Gender 是 F。而在第 3 行 Name 是 Mark,Age 是 25 和 Gender 是 F,我们可以看到 Age 有多个值,那么我们必须删除包含标记的行
好的,这很棘手,所以我将解释每一行。
import pandas as pd
df = pd.DataFrame({'Name' : ['Mark', 'Mark', 'Mark', 'Mark', 'Mark', 'Nick', 'Nick', 'John', 'Sunny', 'Sunny'],
'Age' : ['22', '22', '25', '25', '17', '20', '20', '17', '23', '23'],
'Gender' : ['F', 'F', 'F', 'F', 'F', 'F', 'F', 'M', 'M', 'M']})
print(df)
# First, drop all the rows that are exact duplicates of each other.
df1 = df.drop_duplicates()
print(df1)
# If any rows that remain have a duplicate name, those need to go.
df2 = df1.duplicated('Name')
print(df2)
# Go build a DF with just the names that were duplicated.
df3 = df1[df2]['Name']
print(df3)
# Find all the rows in the original df that have a name in this list,
# invert that set, and the result is what we want.
df4 = df[~df.Name.isin(df3)]
print(df4)
这些操作中的几个可以组合成一个单行,但我认为这使它更清晰。 我添加了空行来分隔输出中的数据帧。
输出:
Name Age Gender
0 Mark 22 F
1 Mark 22 F
2 Mark 25 F
3 Mark 25 F
4 Mark 17 F
5 Nick 20 F
6 Nick 20 F
7 John 17 M
8 Sunny 23 M
9 Sunny 23 M
Name Age Gender
0 Mark 22 F
2 Mark 25 F
4 Mark 17 F
5 Nick 20 F
7 John 17 M
8 Sunny 23 M
0 False
2 True
4 True
5 False
7 False
8 False
dtype: bool
2 Mark
4 Mark
Name: Name, dtype: object
Name Age Gender
5 Nick 20 F
6 Nick 20 F
7 John 17 M
8 Sunny 23 M
9 Sunny 23 M
单行答案:
df[df.Name.isin((s:=df.drop_duplicates().groupby(['Name']).size().eq(1)).index[s])]
结果是:
Name Age Gender
5 Nick 20 F
6 Nick 20 F
7 John 17 M
8 Sunny 23 M
9 Sunny 23 M
也许值得注意的是:walrus-operator 仍然为 Python 的垃圾收集器最终将取消分配的变量s
分配内存。 如果您需要一个表示任何Name
是否具有不同行的Series
,如下所示,那么值得明确分配它。
>>> s
Name
John True
Mark False
Nick True
Sunny True
dtype: bool
在您的计算中的任何其他地方,可能值得将其显式分配给您维护引用的变量。
解释:
# from the OG df
df[
# boolean mask if the name is in
df.Name.isin(
# walrus-operator to temporarily hold result
# drop the duplicate rows (duplicates name + age + gender)
(s:=df.drop_duplicates()
# group on Name
.groupby(['Name'])
# after dropping duplicates, there's only one record
# i.e. no different age/gender records for same name
.size().eq(1))
# mask on names where no-duplicates is true, drop names where false
).index[s]
# pass as series to `df.Name.isin`
)
]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.