pandas按组分组并使用最小值更新

7

我的数据框:

dfd = pd.DataFrame({'A': ['Apple','Apple', 'Apple','Orange','Orange','Orange','Pears','Pears'],
                    'B': [1,2,9,6,4,3,2,1]
                   })
       A    B
0   Apple   1
1   Apple   2
2   Apple   9
3   Orange  6
4   Orange  4
5   Orange  3
6   Pears   2
7   Pears   1

期望结果:

   A    new_B   old_B
0   Apple   1   1
1   Apple   1   2
2   Apple   1   9
3   Orange  3   6
4   Orange  3   4
5   Orange  3   3
6   Pears   1   2
7   Pears   1   1

期望的数据框:new_values包含该组中的最小值。对于苹果,列B的最小值为1,因此所有苹果的新值都为1,同样地,橙子的列B的最小值为3,被替换为new_b列。

第二个期望的输出: 一旦达到上述期望的输出,我必须为每个组创建SQL语句并写入文件: 基本上,迭代每一行并编写SQL查询:

sql_query= "update test_tbl "\
    "set id =  {0}"\
    "where id = {1}"\
    "and A = '{2}' ".format(new_b,old_b,A)

print(sql_query, file=open("output.sql", "a"))

2
使用 df.groupby('A').apply(min) - ssm
2个回答

10

使用GroupBy.transform处理与原始df相同大小的Series

dfd['new_B'] = dfd.groupby('A')['B'].transform('min')
print (dfd)
        A  B  new_B
0   Apple  1      1
1   Apple  2      1
2   Apple  9      1
3  Orange  6      3
4  Orange  4      3
5  Orange  3      3
6   Pears  2      1
7   Pears  1      1

如果列的顺序很重要,可以使用 insertrename
dfd.insert(1, 'new_B', dfd.groupby('A')['B'].transform('min'))
dfd = dfd.rename(columns={'B':'old_B'})
print (dfd)
        A  new_B  old_B
0   Apple      1      1
1   Apple      1      2
2   Apple      1      9
3  Orange      3      6
4  Orange      3      4
5  Orange      3      3
6   Pears      1      2
7   Pears      1      1

如果无法使用 transform,这里有一个替代方案:
#aggregate by min
s = dfd.groupby('A')['B'].min()
print (s)
A
Apple     1
Orange    3
Pears     1
Name: B, dtype: int64

#insert and map
dfd.insert(1, 'new_B', dfd['A'].map(s))
dfd = dfd.rename(columns={'B':'old_B'})
print (dfd)
        A  new_B  old_B
0   Apple      1      1
1   Apple      1      2
2   Apple      1      9
3  Orange      3      6
4  Orange      3      4
5  Orange      3      3
6   Pears      1      2
7   Pears      1      1

我必须为每个组使用旧值和新值创建SQL查询,除了逐行迭代之外,是否有其他替代方法? - min2bro
@min2bro - 我不明白,为什么要迭代?难道不能使用 transform 吗? - jezrael
@min2bro - 添加了聚合和map的替代解决方案。 - jezrael
@min2bro - 很不幸,sql 对我来说很难,所以我不懂。但是在我看来,最好的方法是将输出 DataFrame 添加到 SQL 表中,然后在纯 SQL 中使用左连接。 - jezrael
使用 transform 而不是 min 有什么优势?谢谢。 - tommy.carstensen
1
@tommy.carstensen - 它创建了一个新的列,其中每个组都填充了最小值,因此所有其他列都不会改变。如果聚合min,则行数会减少,换句话说,与原始数据相比,行数会更少,因为进行了聚合。 - jezrael

1

我认为下面的脚本可以实现它

import pandas as pd

dfd = pd.DataFrame({'A': ['Apple','Apple', 'Apple','Orange','Orange','Orange','Pears','Pears'],
                    'B': [1,2,9,6,4,3,2,1]
                   })

dfd_1 = dfd.groupby(['A'], as_index=False).agg({'B': 'min'})

dfd = pd.merge(dfd_1, dfd, how='left', left_on=['A'], right_on=['A'])

dfd.columns = ['A', 'new_B','old_B']

更新了我的问题。 - min2bro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接