如果值在列表中,则 Pandas 数据框中的重复行
Posted
技术标签:
【中文标题】如果值在列表中,则 Pandas 数据框中的重复行【英文标题】:Duplicate Rows in Pandas Dataframe if Values are in a List 【发布时间】:2020-02-27 18:46:49 【问题描述】:我有一个如下所示的数据框:
fruit cost
apples 2
oranges 3
bananas 5
grapefruit 1
我想传递一个包含指定“fruit”列值的列表,并使用它来复制数据框中的这些行。例如,重复的fruits = ['apples', 'oranges']
。
然后应将这些行复制回数据框中,并使用额外的列表示它们是副本(可以是二进制 1/0)。
【问题讨论】:
你的预期输出是什么? 你想要df['indicator'] = df['fruit'].isin(fruits)
吗?
我只想复制“橙子”和“苹果”,所以我已经指定了值。所需的输出是在数据框中复制这些行并创建一个新列,标记哪些行是原始行,哪些行是副本。
【参考方案1】:
使用Series.isin
获取匹配行和重复使用DataFrame.append
到原始数据,DataFrame.assign
用于指示列:
duplicated = ['apples', 'oranges']
df1 = df[df['fruit'].isin(duplicated)].assign(new=1)
df = df.assign(new=0).append(df1, ignore_index=True)
print (df)
fruit cost new
0 apples 2 0
1 oranges 3 0
2 bananas 5 0
3 grapefruit 1 0
4 apples 2 1
5 oranges 3 1
另一个想法是在concat
中使用参数keys
- 它创建由0
和1
填充的新级别,因此第一级需要DataFrame.reset_index
来将此级别转换为列:
df = (pd.concat([df, df1], keys=(0,1))
.rename_axis(('new', None))
.reset_index(level=0)
.reset_index(drop=True))
print (df)
new fruit cost
0 0 apples 2
1 0 oranges 3
2 0 bananas 5
3 0 grapefruit 1
4 1 apples 2
5 1 oranges 3
【讨论】:
谢谢!跟进 q - 如果我现在想指定该行,即重复苹果的位置(水果 = 苹果,新 = 1)并且我想用“苹果汁”替换“苹果”,我该如何替换?跨度> @dataelephant 使用m =(df['fruit'] =='apples') & (df['new'] ==1)
然后df.loc[m, 'fruit'] = "apple juice"
@dataelephant 也检查this。【参考方案2】:
你可以使用concat:
result = pd.concat([df, df[df.fruit.isin(fruits)].assign(new=1)], sort=False).fillna(0)
输出
fruit cost new
0 apples 2 0.0
1 oranges 3 0.0
2 bananas 5 0.0
3 grapefruit 1 0.0
0 apples 2 1.0
1 oranges 3 1.0
作为替代方案,您可以在 concat 之前使用 default_value=0 重新索引:
filtered = df[df.fruit.isin(fruits)].assign(new=1)
result = pd.concat([df.reindex(columns=filtered.columns, fill_value=0), filtered], sort=False)
print(result)
输出
fruit cost new
0 apples 2 0
1 oranges 3 0
2 bananas 5 0
3 grapefruit 1 0
0 apples 2 1
1 oranges 3 1
【讨论】:
以上是关于如果值在列表中,则 Pandas 数据框中的重复行的主要内容,如果未能解决你的问题,请参考以下文章
如果所有行的列中只有一个值,则折叠 Pandas 数据框中的行