【问题标题】:how to concatenate same row names in same column on python dataframe如何在python数据框的同一列中连接相同的行名
【发布时间】:2022-01-08 14:38:09
【问题描述】:

我有一个像这样的简单数据框:

df = pd.DataFrame({'class':['a','b','c','d','e'],
                  'name':['Adi','leon','adi','leo','andy'],
                  'age':['9','8','9','9','8'],
                   'score':['40','90','35','95','85']})

那么结果是这样的

 class  name   age  score
    a   Adi     9   40
    b   leon    8   90
    a   adi     9   35
    d   leo     9   95
    e   andy    8   85

我如何将名为“Adi”的行与同一列中的“adi”组合在一起,而他只有一个人,而分数“Adi”是 75,而不是 40 和 35

【问题讨论】:

  • 您可以将它们全部转换为上限或下限,然后将它们分组并求和

标签: python dataframe data-science


【解决方案1】:

在将name 列设为小写后,您可以使用pandas.DataFrame.<b>groupby</b>pandas.DataFrame.<b>aggregate</b>

import pandas as pd

df = pd.DataFrame({
    'class': ['a', 'b', 'c', 'd', 'e'],
    'name': ['Adi', 'leon', 'adi', 'leo', 'andy'],
    'age': ['9', '8', '9', '9', '8'],
    'score': ['40', '90', '35', '95', '85']
})
df['name'] = df['name'].str.lower()
df['score'] = df['score'].astype(int)
aggregate_funcs = {
    'class': lambda s: ', '.join(set(s)),
    'age': lambda s: ', '.join(set(s)),
    'score': sum
}
df = df.groupby(df['name']).aggregate(aggregate_funcs)
print(df)

输出:

     class age  score
name                 
adi   c, a   9     75
andy     e   8     85
leo      d   9     95
leon     b   8     90

【讨论】:

  • 关于your earlier comment(问题已被删除,无法在那里回复):这不是 O(1) 空间,而是 O(n) 空间。例如,nums = list(range(1, 10**6))tracemalloc 报告您使用 28 MB。正如预期的那样,有一百万个 int 对象每个占用 28 个字节。
  • 是的,对不起,我的意思是 O(1) 额外的额外空间,因为 nums 必须作为参数传递。
  • 不确定你的意思。就“额外的”空间而言,它不是 O(1)。除非你以我看不到的方式定义它? :-) 您正在那里创建 28 MB 的附加数据。对于类似的解决方案,我有两个想法,实际上是 O(1) 额外空间,其中一个能够最终恢复数据(我认为这是现实世界中至少应该做的......如果你在工作,我有点怀疑你会得到一个 LGTM :-)
  • 你所说的一切都是有道理的,就空间而言,它将是 O(N)。然而,我在面试问题中看到了一些与图像处理的 API 设计相关的问题,涉及 1、0 表示黑白像素的 2D 矩阵的操作,如扩张等。在这些问题中,作者提到如果候选人谈论创建两个独立函数的可能性,即一个对输入图像具有破坏性(以及想要一个的原因),另一个创建并返回修改后的副本,这是一个积极的信号。
  • 我同意这一点,尽管我会说那是相当不同的,因为在这些情况下的输出是修改后的矩阵,对吗?即,修改它可能是期望的效果。另一方面,在我们的例子中,输出是单个 int,并且您的代码修改输入列表不是作为 desired 效果而是作为 side 效果。 那是我认为它不是那么好。
【解决方案2】:

drop_duplicates() 是使用 pandas 的最佳方式

df['name'] = df['name'].str.lower()
df['score'] = df['score'].astype(int)
df['score'] = df['score'].groupby(df['name']).transform(sum)
df.drop_duplicates(subset='name',keep='first',inplace=True)

输出:

  class  name age  score
0     a   adi   9     75
1     b  leon   8     90
3     d   leo   9     95
4     e  andy   8     85

如果你设置keep='last',你会得到这个输出:

  class  name age  score
1     b  leon   8     90
2     c   adi   9     75
3     d   leo   9     95
4     e  andy   8     85

【讨论】:

    猜你喜欢
    • 2018-09-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-20
    • 2020-02-01
    • 1970-01-01
    • 2020-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多