基于用户的编码/转换及其在Panda中的交互



我有一个数据帧,它看起来像这样:

user_id:表示用户

question_id:表示问题编号

user_answer:用户为(A、B、C、D)中的特定问题选择了哪个选项

correct_answer:这个特定问题的正确答案是什么

正确:1.0这意味着用户的答案是正确的

elapsed_time:它表示用户回答问题所花费的时间(以分钟为单位)

时间戳:每个交互的UNIX时间戳

real_date:我添加了这个列,并将时间戳转换为人工日期&时间

tbody>
**user_*iD*** **solving_*id*** **bundle_*id***
1 1547794902000 周五,2019年1月18日上午7:01:42
1 1547795130000 1月18日,星期五,2019年上午7:05:30
1 1547795370000 1月18日,星期五,2019年上午7:09:30
2 1547806170000 1月18日,星期五,2019年上午10:09:30
2 1547802150000 1月18日,星期五,2019年9:02:30 AM
2 1547803230000 1月18日,星期五,2019年9:20:30 AM
2 1547802730000 1月18日,星期五,2019年上午9:12:10
3 154777111000 1月18日,星期五,2019年12:25:10 AM
3 1547770801000 1月18日,星期五,2019年12:20:10 AM
3 15477770390000 1月18日,星期五,2019年12:13:10 AM
104 1553040610000 3月20日,星期三,2019年12:10:10 AM
104 15530400547000 3月20日,星期三,2019年12:09:07 AM
104 1553040285000 3月20日,星期三,2019年12:04:45 AM

首先使用groupbycumcount为每个bundle元素创建最终值,然后调整数据帧。最后重新索引以获得所有列:

bundle = [f'b{i}' for i in range(1, 16)]
values = df.sort_values('timestamp').groupby('user_iD').cumcount().add(1)
out = (
df.assign(value=values).pivot_table('value', 'user_iD', 'bundle_id', fill_value=0)
.reindex(bundle, axis=1, fill_value=0)
)

输出:

>>> out
bundle_id  b1  b2  b3  b4  b5  b6  b7  b8  b9  b10  b11  b12  b13  b14  b15
user_iD                                                                    
1           1   2   0   0   3   0   0   0   0    0    0    0    0    0    0
2           1   0   0   0   0   0   2   0   0    4    0    0    0    0    3
3           0   0   1   0   0   0   0   0   0    2    0    3    0    0    0
104         1   0   0   2   0   3   0   0   0    0    0    0    0    0    0
>>> out.reset_index().rename_axis(columns=None)
user_iD  b1  b2  b3  b4  b5  b6  b7  b8  b9  b10  b11  b12  b13  b14  b15
0        1   1   2   0   0   3   0   0   0   0    0    0    0    0    0    0
1        2   1   0   0   0   0   0   2   0   0    4    0    0    0    0    3
2        3   0   0   1   0   0   0   0   0   0    2    0    3    0    0    0
3      104   1   0   0   2   0   3   0   0   0    0    0    0    0    0    0

由于缺乏更多的Python式经验,我建议使用以下(部分注释)代码片段,该代码片段无论如何都没有优化,仅基于基本pandas.DataFrameAPI参考。

import pandas as pd
import io
import sys
data_string = '''
user_iD;question_id;user_answer;correct_answer;correct;elapsed_time;solving_id;bundle_id;timestamp
1;1;A;A;1.0;5.00;1;b1;1547794902000
1;2;D;D;1.0;3.00;2;b2;1547795130000
1;5;C;C;1.0;7.00;5;b5;1547795370000
2;10;C;C;1.0;5.00;10;b10;1547806170000
2;1;B;B;1.0;15.0;1;b1;1547802150000
2;15;A;A;1.0;2.00;15;b15;1547803230000
2;7;C;C;1.0;5.00;7;b7;1547802730000
3;12;A;A;1.0;1.00;25;b12;1547771110000
3;10;C;C;1.0;2.00;10;b10;1547770810000
3;3;D;D;1.0;5.00;3;b3;1547770390000
104;6;C;C;1.0;6.00;6;b6;1553040610000
104;4;A;A;1.0;5.00;4;b4;1553040547000
104;1;A;A;1.0;2.00;1;b1;1553040285000
'''
df = pd.read_csv( io.StringIO(data_string), sep=";", encoding='utf-8')
# get only necessary columns ordered by timestamp
df_aux = df[['user_iD','bundle_id','correct', 'timestamp']].sort_values(by=['timestamp']) 
# hard coded new headers (possible to build from real 'bundle_id's)
df_new_headers = ['b{}'.format(x+1) for x in range(15)]
df_new_headers.insert(0, 'user_iD')
dict_answered = {}
# create a new dataframe (I'm sure that there is a more Pythonish solution)
df_new_data = []
user_ids = sorted(set( [x for label, x in df_aux.user_iD.items()]))
for user_id in user_ids:
dict_answered[user_id] = 0
if len( sys.argv) > 1 and sys.argv[1]:
# supplied arg in the next line for better result readability
df_new_values = [sys.argv[1].strip('"').strip("'")
for x in range(len(df_new_headers)-1)]
else:
# zeroes (original assignment)
df_new_values = [0 for x in range(len(df_new_headers)-1)]

df_new_values.insert(0, user_id)
df_new_data.append(df_new_values)
df_new = pd.DataFrame(data=df_new_data, columns=df_new_headers)
# fill the new dataframe using values from the original one
for aux in df_aux.itertuples(index=True, name=None):
if aux[3] == 1.0:
# add 1 to number of already answered questions for current user 
dict_answered[aux[1]] += 1
df_new.loc[ df_new["user_iD"] == aux[1], aux[2]] = dict_answered[aux[1]]    
print( df_new)

输出示例

示例:.SO70751715.py

user_iD  b1  b2  b3  b4  b5  b6  b7  b8  b9  b10  b11  b12  b13  b14  b15
0        1   1   2   0   0   3   0   0   0   0    0    0    0    0    0    0
1        2   1   0   0   0   0   0   2   0   0    4    0    0    0    0    3
2        3   0   0   1   0   0   0   0   0   0    2    0    3    0    0    0
3      104   1   0   0   2   0   3   0   0   0    0    0    0    0    0    0

示例:.SO70751715.py .

user_iD b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
0        1  1  2  .  .  3  .  .  .  .   .   .   .   .   .   .
1        2  1  .  .  .  .  .  2  .  .   4   .   .   .   .   3
2        3  .  .  1  .  .  .  .  .  .   2   .   3   .   .   .
3      104  1  .  .  2  .  3  .  .  .   .   .   .   .   .   .

示例:.SO70751715.py ''

user_iD b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
0        1  1  2        3
1        2  1                 2         4                   3
2        3        1                     2       3
3      104  1        2     3

我想您正在寻找LabelEncoder。首先导入库:

#Common Model Helpers
from sklearn.preprocessing import LabelEncoder

然后您应该能够将对象转换为类别:

#CONVERT: convert objects to category 

#code categorical data
label = LabelEncoder()   
dataset['question_id'] = label.fit_transform(dataset['question_id']
dataset['user_answer'] = label.fit_transform(dataset['user_answer'])
dataset['correct_answer'] = label.fit_transform(dataset['correct_answer'])

或者只使用以下内容:

dataset.apply(LabelEncoder().fit_transform)

最新更新