我有这样的数据框(请丢弃第一栏):
user_id created_at count
1 12136 2017-02-19 4
2 12136 2017-02-16 4
3 12136 2017-02-17 2
4 72349 2017-02-17 8
5 72349 2017-02-19 2
7 72672 2017-02-20 3
8 72672 2017-02-19 2
所以,我想将这个值映射到从0开始的整数值:
12136 -> 0
72349 -> 1
72672 -> 2
同样,对于created_at列(从最小值开始)
2017-02-16 -> 0
2017-02-17 -> 1
2017-02-19 -> 2
2017-02-20 -> 3
最后我应该有这个数据框(请注意,在没有用户活动的日期添加0值):
user_id created_at count
0 0 4
0 1 2
0 2 4
0 3 0
1 0 0
1 1 8
1 2 2
1 3 0
2 0 0
2 1 0
2 2 2
2 3 3
此外,我需要获取这些列表:
label1 = [12136, 72349, 72672]
label2 = ['2017-02-16', '2017-02-17', '2017-02-19', '2017-02-20']
我想知道是否有任何方法可以帮助我有效地执行此操作?
答案 0 :(得分:2)
您可以将列转换为类别并获取映射字典
df['user_id']= df['user_id'].astype('category')
label1 = dict(enumerate(df['user_id'].cat.categories))
df['created_at']= df['created_at'].astype('category')
label2 = dict(enumerate(df['created_at'].cat.categories))
现在将列值转换为类别代码
df[['user_id', 'created_at']] = df[['user_id', 'created_at']].apply(lambda x: x.cat.codes)
你得到了
user_id created_at count
1 0 2 4
2 0 0 4
3 0 1 2
4 1 1 8
5 1 2 2
7 2 3 3
8 2 2 2
label1的
{0: 12136, 1: 72349, 2: 72672}
LABEL2
{0: '2017-02-16', 1: '2017-02-17', 2: '2017-02-19', 3: '2017-02-20'}
答案 1 :(得分:2)
首先,获取您的清单。
list1 = df.user_id.unique()
print(list1)
array([12136, 72349, 72672])
list2 = df.created_at.unique()
print(list2)
array(['2017-02-19', '2017-02-16', '2017-02-17', '2017-02-20'], dtype=object)
将user_id
和created_at
列转换为cat
代码。
df['user_id'] = df['user_id'].astype('category').cat.codes
df['created_at'] = df['created_at'].astype('category').cat.codes
print(df)
user_id created_at count
1 0 2 4
2 0 0 4
3 0 1 2
4 1 1 8
5 1 2 2
7 2 3 3
8 2 2 2
使用groupby
和reindex
操作。
df = df.set_index('created_at').groupby('user_id', as_index=False)\
.apply(lambda x: x.reindex(df.created_at.unique()))\
.sort_index().reset_index([1])
清理你的专栏。
df.user_id = df.groupby(level=0).user_id.transform(lambda x: x.ffill().bfill())
df['count'] = df['count'].fillna(0)
print(df.astype(int))
created_at user_id count
0 0 0 4
0 1 0 2
0 2 0 4
0 3 0 0
1 0 1 0
1 1 1 8
1 2 1 2
1 3 1 0
2 0 2 0
2 1 2 0
2 2 2 2
2 3 2 3
答案 2 :(得分:1)
我的解决方案将每列中的唯一值转换为np.array
,并使用np.argwhere
获取排序后的索引,然后再将其放回DataFrame
。您可以按如下方式将每个转换放入单行:
# Just creating your DataFrame
df = pd.DataFrame({'user_id': [12136, 12136, 12136, 72349, 72349,
72672, 72672],
'created_at': ['2017-02-19', '2017-02-16',
'2017-02-17', '2017-02-17',
'2017-02-19', '2017-02-20',
'2017-02-19'],
'count': [4, 4, 2, 8, 2, 3, 2]})
label1 = np.sort(np.array(df.user_id.unique()))
label2 = pd.to_datetime(np.sort(np.array(df.created_at.unique())))
df['user_id'] = df.apply(lambda x: np.argwhere(label1 == x.user_id)[0][0],
axis=1)
df['created_at'] = df.apply(lambda x: np.argwhere(label2 == x.created_at)[0][0], axis=1)
答案 3 :(得分:1)
以下是我的答案:
dfx_users = pd.DataFrame({'user_id': df['user_id'].unique(), 'u_id': range(0, len(df['user_id'].unique()))})
dfx_users['key'] = 1
dfx_dates = pd.DataFrame({'created_at': df['created_at'].unique(), 'd_id': range(0, len(df['created_at'].unique()))})
dfx_dates['key'] = 1
dfxx = pd.merge(dfx_users, dfx_dates, on='key').drop('key', 1)
dfxx.sort_values(['user_id', 'created_at'], ascending=[True, True])
dfxx.merge(dfx[['user_id', 'created_at', 'count']],
on=['user_id', 'created_at'], how='left').fillna(0)[['u_id', 'd_id', 'count']]
u_id d_id count
0 0 4
0 1 2
0 2 4
0 3 0
1 0 0
1 1 8
1 2 2
1 3 0
2 0 0
2 1 0
2 2 2
2 3 3