在 pandas 数据框中删除重复项
Drop duplicates in pandas Dataframe
我有一个 DataFrame
Type Numer master width
xyz 465_0 123 305
xyz 465_0 123 305
xyz 465_0 123 305
xyz 465_0 123 315
xyz 465_1 123 305
xyz 465_1 123 305
xyz 465_1 123 305
xyz 465_1 123 315
xyz 465_2 123 305
xyz 465_2 123 305
xyz 465_2 123 305
xyz 465_2 123 315
xyz 465_3 123 305
xyz 465_3 123 305
xyz 465_3 123 305
xyz 465_3 123 315
据此我需要以下 DataFrame
Type Numer master width
xyz 465_0 123 305
xyz 465_1 123 305
xyz 465_2 123 305
xyz 465_3 123 315
我的尝试是:
df[['Numer1', 'dig']] = df['Numer'].str.split("_", expand=True)
df = df.drop('Numer', axis = 1)
df.drop_duplicates()
但它没有给我结果。我想以通用的方式编写它,因为我有多种类型。
数据:
{'Type': ['xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz',
'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz'],
'Numer': ['465_0', '465_0', '465_0', '465_0', '465_1', '465_1', '465_1', '465_1',
'465_2', '465_2', '465_2', '465_2', '465_3', '465_3', '465_3', '465_3'],
'master': [123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123],
'width': [305, 305, 305, 315, 305, 305, 305, 315, 305, 305, 305, 315, 305, 305, 305, 315]}
我们可以使用 groupby
+ cumcount
为每个“数字”创建一个 group-specific 排名;然后过滤“数字”中的后缀与组中排名匹配的行:
out = df[df['Numer'].str.split('_').str[1].astype(int) == df.groupby('Numer').cumcount()].drop(columns='rank')
输出:
Type Numer master width
0 xyz 465_0 123 305
5 xyz 465_1 123 305
10 xyz 465_2 123 305
15 xyz 465_3 123 315
我从你的问题中了解到,你正试图将每个 Numer
组中的 width
模式“折叠”成一个 DataFrame
,它只有唯一的组(Numer
) 值和相同的 width
模式
一种方法是在反转组后使用 itertools
库中的 zip_longest
函数 -
from itertools import zip_longest
rev_zip_longest = list(zip_longest(*[reversed(df[col].unique()) for col in df.columns]))
# [('xyz', '465_3', 123, 315),
# (None, '465_2', None, 305),
# (None, '465_1', None, None),
# (None, '465_0', None, None)]
df2 = pd.DataFrame(rev_zip_longest)
df2.columns = df.columns
df2 = df2.fillna(method='ffill')
# Type Numer master width
# 0 xyz 465_3 123.0 315.0
# 1 xyz 465_2 123.0 305.0
# 2 xyz 465_1 123.0 305.0
# 3 xyz 465_0 123.0 305.0
此代码也适用:
res = pd.concat([g.take([i.split('_')[1]]) for i,g in df.groupby('Numer')])
print(res)
'''
Type Numer master width
0 xyz 465_0 123 305
5 xyz 465_1 123 305
10 xyz 465_2 123 305
15 xyz 465_3 123 315
我有一个 DataFrame
Type Numer master width
xyz 465_0 123 305
xyz 465_0 123 305
xyz 465_0 123 305
xyz 465_0 123 315
xyz 465_1 123 305
xyz 465_1 123 305
xyz 465_1 123 305
xyz 465_1 123 315
xyz 465_2 123 305
xyz 465_2 123 305
xyz 465_2 123 305
xyz 465_2 123 315
xyz 465_3 123 305
xyz 465_3 123 305
xyz 465_3 123 305
xyz 465_3 123 315
据此我需要以下 DataFrame
Type Numer master width
xyz 465_0 123 305
xyz 465_1 123 305
xyz 465_2 123 305
xyz 465_3 123 315
我的尝试是:
df[['Numer1', 'dig']] = df['Numer'].str.split("_", expand=True)
df = df.drop('Numer', axis = 1)
df.drop_duplicates()
但它没有给我结果。我想以通用的方式编写它,因为我有多种类型。
数据:
{'Type': ['xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz',
'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz'],
'Numer': ['465_0', '465_0', '465_0', '465_0', '465_1', '465_1', '465_1', '465_1',
'465_2', '465_2', '465_2', '465_2', '465_3', '465_3', '465_3', '465_3'],
'master': [123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123],
'width': [305, 305, 305, 315, 305, 305, 305, 315, 305, 305, 305, 315, 305, 305, 305, 315]}
我们可以使用 groupby
+ cumcount
为每个“数字”创建一个 group-specific 排名;然后过滤“数字”中的后缀与组中排名匹配的行:
out = df[df['Numer'].str.split('_').str[1].astype(int) == df.groupby('Numer').cumcount()].drop(columns='rank')
输出:
Type Numer master width
0 xyz 465_0 123 305
5 xyz 465_1 123 305
10 xyz 465_2 123 305
15 xyz 465_3 123 315
我从你的问题中了解到,你正试图将每个 Numer
组中的 width
模式“折叠”成一个 DataFrame
,它只有唯一的组(Numer
) 值和相同的 width
模式
一种方法是在反转组后使用 itertools
库中的 zip_longest
函数 -
from itertools import zip_longest
rev_zip_longest = list(zip_longest(*[reversed(df[col].unique()) for col in df.columns]))
# [('xyz', '465_3', 123, 315),
# (None, '465_2', None, 305),
# (None, '465_1', None, None),
# (None, '465_0', None, None)]
df2 = pd.DataFrame(rev_zip_longest)
df2.columns = df.columns
df2 = df2.fillna(method='ffill')
# Type Numer master width
# 0 xyz 465_3 123.0 315.0
# 1 xyz 465_2 123.0 305.0
# 2 xyz 465_1 123.0 305.0
# 3 xyz 465_0 123.0 305.0
此代码也适用:
res = pd.concat([g.take([i.split('_')[1]]) for i,g in df.groupby('Numer')])
print(res)
'''
Type Numer master width
0 xyz 465_0 123 305
5 xyz 465_1 123 305
10 xyz 465_2 123 305
15 xyz 465_3 123 315