在Python中创建一个基于另一列递增的列

6

我目前把注意力从R转向Python。在R中,我经常使用data.table,但有时很难找到Python中一些函数的等价物。

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

df = pd.DataFrame({'A':['abc','def', 'def', 'abc', 'def', 'def','abc'],'B':[13123,45,1231,463,142131,4839, 4341]})

     A       B  
0  abc   13123    
1  def      45  
2  def    1231  
3  abc     463  
4  def  142131  
5  def    4839
6  abc    4341
我需要创建一列,该列基于A和B递增地从1开始计数,以指示B的递增顺序。因此,我首先创建排序后的数据框,我要创建的列是以下的C:
    A       B   C
1  abc     463  1
6  abc    4341  2
0  abc   13123  3
3  def      45  1
2  def    1231  2
5  def    4839  3
4  def  142131  4
在R中,使用library(data.table),可以轻松地在一行代码内创建一个新列并将其添加到原始数据表中:

df[, C := 1:.N, by=A]

我查看了一些资料,认为可能可以利用以下内容:

df.groupby('A').size()

df['B'].argsort()

但不确定如何继续操作并将新列加入原始数据框。如果有人能给出任何指示,那就非常有帮助了。
非常感谢!

1
这似乎是不正确的 data.table 语法。你的意思是 df[,C:=1:.N,by=A] 吗?另外为什么要先用 setkey,你可以随意使用 by - Matt Dowle
是的,抱歉,我已经在R代码中纠正了拼写错误。感谢您指出。无论如何,我更感兴趣的是找到一种用Python实现这个功能的方法。 - S.zhen
还是不对。这将复制df的整个内容,这是R的data.frame的一项(相对较差)功能,而data.table进行了改进。如果你错过了这一点,那么你可能没有经常使用data.table - Matt Dowle
这只是一个小的数据表,仅用于演示,而我在寻找Python解决方案时并不认为专注于此有多大意义。感谢您提供的R知识输入。 - S.zhen
3
因为 :=data.table 的一个重要特性,而你在发布问题时打上了Python和pandas的标签,作为 data.table 的作者,我不希望看到 data.table 在广大受众面前被错误使用。请注意语境,避免误导他人使用。 - Matt Dowle
1
好的,没问题。我明白你的意思了。我已经修改了上面的R代码。 - S.zhen
3个回答

6
In [61]: df
Out[61]:
     A       B
1  abc     463
6  abc    4341
0  abc   13123
3  def      45
2  def    1231
5  def    4839
4  def  142131

In [62]: df['C'] =  df.groupby('A')['A'].transform(lambda x: pd.Series(range(1, len(x)+1), index=x.index))

In [63]: df
Out[63]:
     A       B  C
1  abc     463  1
6  abc    4341  2
0  abc   13123  3
3  def      45  1
2  def    1231  2
5  def    4839  3
4  def  142131  4

那个代码是可以运行的(除了排序后的数据框实际上是不同的)。非常感谢! - S.zhen
从仅按A排序的帧开始,我编辑了这个顺序,现在与示例中的顺序相同。 - Wouter Overmeire
嗨Wouter,感谢你详尽的回答。作为后续问题,我如何创建一个名为['D']的列,它从B的最小值开始枚举,以便在此情况下它看起来像:[463, 464, 465, 45, 46, 47, 48]?(抱歉我不知道如何在评论中正确格式化!) - S.zhen
实际上,我想我已经弄清楚了:df['D'] = df.groupby('A')['B'].transform(lambda x: pd.Series(range(min(x), min(x) + len(x)), index=x.index)) 很好用!(我还搞清楚了如何在注释中进行格式化) - S.zhen

1

作为比较,正确的 data.table 语法是:

df[, C := 1:.N, by=A]

这通过引用df添加了一个新的列C。 := 运算符是R的data.table包的一部分。 它允许您添加和删除列,并按组,按引用对data.table的子集进行赋值,而完全不需要复制。


这个操作有没有一个快速的名字来表示它的双倍?比如,如果我想展开一个重复递增的序列,而不是每次列的值改变时都重复一遍。(如果这不是一个快速的答案,请告诉我,我会提出一个问题。谢谢。) - bright-star

0

索引魔法似乎是另一种方法:

df['C']=df.sort(['A','B'],inplace=True).groupby('A').reset_index().index.labels[1]

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