Python - 用反向计数器附加行号
Posted
技术标签:
【中文标题】Python - 用反向计数器附加行号【英文标题】:Python - Appending row number with reverse counter 【发布时间】:2019-03-27 23:26:05 【问题描述】:我还有另一个 Python 问题。这可能可以在循环的帮助下实现,但是我正在寻找更精简的解决方案
假设我有一个像这样的数据框:
我正在寻找一个代码来生成列 ID,当列 Sold 中的值发生变化时,该列 ID 不超过一个递减计数器 - 即,对于每个销售员,我希望 ID 列检索剩余天数,直到售价发生变化。 例如,在 2018 年 1 月 1 日,销售员 Joe 的 ID = 2,因为信号会在 2 天内发生变化。
关于如何解决这个问题的任何想法?
非常感谢。 J
【问题讨论】:
请不要将数据作为图像发布。是否也保证您的每一天在每个推销员中都是连续的? 【参考方案1】:设置:
df = pd.DataFrame([
pd.Series(pd.date_range('1/1/2018', '1/7/2018').append(pd.date_range('1/1/2018', '1/7/2018'))),
pd.Series(['Joe']*7 + ['Helen']*7),
pd.Series([1,1,0,0,0,0,1,0,1,1,0,1,0,0]),
]).T
df.columns = ['date', 'salesman', 'sold']
df['date'] = pd.to_datetime(df['date'])
计算:
df['changes'] = df.groupby('salesman')['sold'].expanding().apply(lambda x: (np.diff(x) != 0).sum()).reset_index(drop = True)
df['id'] = df.groupby(['salesman', 'changes']).apply(lambda grp: pd.Series(len(grp) - grp.sort_values('date').reset_index().index)).reset_index(drop = True)
df.drop('changes', axis = 1, inplace = True)
结果:
>>> df
date salesman sold id
0 2018-01-01 Joe 1 2
1 2018-01-02 Joe 1 1
2 2018-01-03 Joe 0 4
3 2018-01-04 Joe 0 3
4 2018-01-05 Joe 0 2
5 2018-01-06 Joe 0 1
6 2018-01-07 Joe 1 1
7 2018-01-01 Helen 0 1
8 2018-01-02 Helen 1 2
9 2018-01-03 Helen 1 1
10 2018-01-04 Helen 0 1
11 2018-01-05 Helen 1 1
12 2018-01-06 Helen 0 2
13 2018-01-07 Helen 0 1
解释:
创建一个 'changes'
列,每次单个销售人员的 'sold
' 字段更改时都会递增。然后对于每个增量组(仍按销售人员分组),获取该组的长度(等于该值的后续行的长度)并从该值中减去每行的索引,按日期排序。该减法的结果将是一个从组长度下降到 1 的序列。重置索引并合并回原始数据帧。这是一个有点令人困惑的解决方案,但它应该可以工作。
【讨论】:
谢谢。并没有真正得到同样的结果。除了 Pandas,您还使用了哪些其他库? 您能否更深入地了解问题所在?错误是什么?我正在使用 pandas .22、numpy 1.14.12 和 python 2.7。这些都是相当标准的包,虽然有点过时。 是的,确实没有什么不寻常的,我也使用它们。错误发生在计算的第二行。 错误很长:ValueError Traceback (most recent call last) 。 ; ValueError: 传递的项目数错误 0,位置意味着 1 我很难在没有看到任何东西的情况下进行调试,但听起来 python 正在尝试将 0 个东西分配给 1 个占位符。即df['id']
没有从等号的 RHS 接收到值。在不将值分配给df['id']
的情况下尝试该行。你从中得到的应该可以帮助你弄清楚你的问题。还可以尝试重新启动你的 python 等等,因为我的环境没有抛出错误。并确保您使用我的设置(为了保持一致性)。以上是关于Python - 用反向计数器附加行号的主要内容,如果未能解决你的问题,请参考以下文章