【问题标题】:Create a column which increments based on another column in Python创建一个基于 Python 中的另一列递增的列
【发布时间】:2012-10-23 13:41:52
【问题描述】:

我目前已将注意力从 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()

但不确定如何从这里开始,以及如何将新列连接回原始数据框。如果有人能给我任何指示,那将非常有帮助。

非常感谢!

【问题讨论】:

  • 这似乎是不正确的data.table 语法。你的意思是df[,C:=1:.N,by=A]?为什么要先setkey,你可以把它留给临时的。
  • 是的,抱歉,我已经更正了 R 代码中的错字。感谢您指出。无论如何,我更感兴趣的是在 Python 中找到一种方法。
  • 那还是错的。这将复制df整个,这是data.table 改进的R 的data.frame 的(有些差的)功能之一。你不可能经常使用data.table,错过了这个。
  • 因为:= by group 是data.table 的主要功能。您已发布到 python 和 pandas 标签,所以作为data.table 的作者,我不希望看到data.table 在广大观众面前被不当使用。
  • 好的,当然。我明白你的意思了。我已经修改了上面的 R 代码。

标签: python r pandas data.table


【解决方案1】:
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

【讨论】:

  • 这行得通(除了排序的数据框实际上不同)。非常感谢!
  • 从仅在 A 上排序的帧开始,我编辑此顺序现在与示例中的相同。
  • 您好 Wouter,感谢您的详尽回答。作为后续问题,我如何创建一个从 B 的最小值枚举的列 ['D'],使其看起来像: [463, 464, 465, 45, 46, 47, 48] 在这个案子? (抱歉不知道如何在评论中正确格式化!)
  • 实际上,我想我已经弄清楚了:df['D'] = df.groupby('A')['B'].transform(lambda x: pd.Series(range(min(x), min(x)+len(x)), index=x.index)) 效果很好! (我也想出了如何在评论中格式化)
【解决方案2】:

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

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

这会通过引用df 添加一个新列 C。 := 运算符是 R 的 data.table 包的一部分。它允许您添加和删除列并分配给 data.table 的子集,按组,按引用,根本没有副本。

【讨论】:

  • 这个操作的对偶有一个简称吗?比如说,如果我想解开一个重复增加的序列,而不是每次一列更改值时都重复。 (如果不是快速回答,请告诉我,我会提出问题。谢谢。)
【解决方案3】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-11
    • 2019-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 2018-02-18
    • 1970-01-01
    相关资源
    最近更新 更多