我有以下数据框
USER_ID MONTH STATUS_ID
0 23026 2019-09-01 2
1 23026 2019-10-01 2
2 23026 2019-11-01 2
3 23026 2019-12-01 2
4 23027 2019-09-01 2
... ... ... ...
123 16546 2018-10-01 2
124 16622 2018-09-01 1
125 16622 2018-10-01 1
126 16622 2018-11-01 1
127 16622 2018-12-01 1
所有用户应有 4 行(4 个月),但期间可以不同 (2018年2月1日-2018年5月1日或2019年2月1日-2019年5月1日...)
我也想这样改造
USER_ID MONTH_1 MONTH_2 MONTH_3 MONTH_4
0 23026 2 2 2 2
1 23027 2 2 2 2
... ... ... ...
123 16546 2 2 1 1
124 16622 1 1 1 1
最后我应该根据 STATUS ID 转换数据帧
USER_ID ID
0 23026 2
1 23027 2
... ... ... ...
123 16546 2
124 16622 1
这是不同月份的ID之间的一种 bool 运算。 知道如何改变这个吗?或者可以更有效地解决这个问题吗?
最佳答案
我认为可能的解决方案是通过 GroupBy.cumcount
计数创建新列并传递至DataFrame.pivot
:
print (df)
USER_ID MONTH STATUS_ID
0 23026 2019-09-01 2
1 23026 2019-10-01 2
2 23026 2019-11-01 2
3 23026 2019-12-01 2
123 16546 2018-09-01 2
123 16546 2018-10-01 2
123 16546 2018-11-01 1
123 16546 2018-12-01 1
124 16622 2018-09-01 1
125 16622 2018-10-01 1
126 16622 2018-11-01 1
127 16622 2018-12-01 1
df['MONTH1'] = 'MONTH_' + df.groupby('USER_ID').cumcount().add(1).astype(str)
df = df.pivot('USER_ID','MONTH1','STATUS_ID')
print (df)
MONTH1 MONTH_1 MONTH_2 MONTH_3 MONTH_4
USER_ID
16546 2 2 1 1
16622 1 1 1 1
23026 2 2 2 2
然后将 1
与 DataFrame.eq
进行比较并通过 DataFrame.any
测试每行是否至少有一个 True
,最后一个map
并转换为DataFrame
:
df1 = df1.eq(1).any(axis=1).map({True:1, False:2}).reset_index(name='ID')
print (df1)
USER_ID ID
0 16546 1
1 16622 1
2 23026 2
详细信息:
print (df1.eq(1))
MONTH1 MONTH_1 MONTH_2 MONTH_3 MONTH_4
USER_ID
16546 False False True True
16622 True True True True
23026 False False False False
关于python - 根据 ID 状态转换数据帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60613649/