我有一个数据帧,它看起来像这样:
user_id:表示用户
question_id:表示问题编号
user_answer:用户为(A、B、C、D)中的特定问题选择了哪个选项
correct_answer:这个特定问题的正确答案是什么
正确:1.0这意味着用户的答案是正确的
elapsed_time:它表示用户回答问题所花费的时间(以分钟为单位)
时间戳:每个交互的UNIX时间戳
real_date:我添加了这个列,并将时间戳转换为人工日期&时间
**user_*iD*** | **solving_*id*** | **bundle_*id*** | tbody>
---|---|---|
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 |
首先使用groupby
和cumcount
为每个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.DataFrame
API参考。
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)