我有一个由许多个人评估者生成的照片评级数据集 每个评估者都有几个图像来评价,每个图像,评估者提供几个不同的评级,加上描述。
因此,举例来说,评分者可能会被要求评价3张不同的照片,并以0-5的比例提供单独的评分,以确定每张照片的快乐,悲伤和有趣。此外,要求评估者提供每张照片的简短文字说明。
同一张照片可能会被多个评分者评分,但并非所有照片都会被相同数量的评分者评分。
目前我的数据采用此格式(每个网址代表一张照片):
rater_id | url1 | url2 | url3 | rating_1(1) | rating_2(1) | rating_1(2) | rating_2(2) | rating_1(3) | rating_2(3) | description(1) | description(2) | description(3)
001 | a | b | c | 3.0 | 2.5 | 4.0 | 1.5 | 5.0 | 5.0 | sunny day | rainy day | foggy day
002 | a | b | d | 1.0 | 4.5 | 3.0 | 3.5 | 1.0 | 3.5 | sunshine | rain | snow
我试图在这里实现一些变革。
首先,我想更改数据框,以便通过照片网址对其进行索引 - 将所有网址字段(url1,url2等)融合到一个长列url
中。含义:
url1 | url2 | url3
-----|------|-----
a | b | c
变为
url
---
a
b
c
在每个url
索引中,有一个rater_id
的嵌套索引,然后有一行该评估者对给定照片的评级和描述。
例如:
| rating_1 | rating_2 | description
url | rater_id
a | 001 | 3.0 | 2.5 | sunny day
| 002 | 1.0 | 4.5 | sunshine
----|-----------|----------|----------|------------
b | 001 | 4.0 | 1.5 | rainy day
| 002 | 4.5 | 3.0 | rain
----|-----------|----------|----------|------------
c | 001 | 5.0 | 5.0 | foggy day
----|-----------|----------|----------|------------
d | 002 | 1.0 | 3.5 | snow
最后,我想汇总每张照片网址的评分和说明: - 数字评级的均值和方差 - 以制表符分隔的所有描述字符串 - 对每张照片进行评分的评估者数量
例如:
url | rating_1_avg | rating_1_var | rating_2_avg | rating_2_var | all_descriptions | total_ratings
a | 2.0 | 2.0 | 3.0 | 2.0 | sunny day sunshine | 2
----|--------------|--------------|--------------|--------------|-----------------------|--------------
b | 4.25 | 0.125 | 2.25 | 1.125 | rainy day rain | 2
----|--------------|--------------|--------------|--------------|-----------------------|--------------
c | 5.0 | NA | 5.0 | NA | foggy day | 1
----|--------------|--------------|--------------|--------------|-----------------------|--------------
d | 1.0 | NA | 3.5 | NA | snow | 1
我使用Pandas reshaping工具尝试了多种方法,包括melt
和wide_to_long
,但我无法弄清楚如何首先将照片网址设为长格式,然后创建一个嵌套索引来排列数据,如上所述。我对Pandas groupby
和基本聚合感到很满意,但这有点超出了我的技能水平。非常感谢任何帮助!
注意:我在这些虚拟数据中给出的字段不是实际数据集中的确切名称,但它们完全遵循相同的命名约定。照片网址均为url1
,url2
等,而评分字段则表示为rating_<rating_category_number>(<url_number>)
,例如。 rating_1(2)
。描述字段表示为description(<url_number>)
,例如。 description(2)
。
这是构建初始数据集的Python代码:
df = pd.DataFrame({'id': {0: '001', 1: '002'},
'url1': {0: 'a', 1: 'a'},
'url2': {0: 'b', 1: 'b'},
'url3': {0: 'c', 1: 'd'}})
df['rating_1(1)'] = [3.0, 1]
df['rating_2(1)'] = [2.5, 4.5]
df['rating_1(2)'] = [4.0, 3]
df['rating_2(2)'] = [1.5, 3.5]
df['rating_1(3)'] = [5.0, 1]
df['rating_2(3)'] = [5.0, 3.5]
df['description(1)'] = ['sunny day','sunshine']
df['description(2)'] = ['rainy day','rain']
df['description(3)'] = ['foggy day','snow']
答案 0 :(得分:2)
您可以先str.contains
找到每个类别的列,然后使用不太知名的pd.lreshape
。 mean
,var
,count
和join
的最后一次汇总列:
#select columns with each category
rat1 = df.columns[df.columns.str.contains(r'rating_1')].tolist()
print rat1
['rating_1(1)', 'rating_1(2)', 'rating_1(3)']
rat2 = df.columns[df.columns.str.contains(r'rating_2')].tolist()
url = df.columns[df.columns.str.contains(r'url')].tolist()
desc = df.columns[df.columns.str.contains(r'description')].tolist()
df = pd.lreshape(df, {'rat1': rat1, 'rat2': rat2,'url': url,'desc': desc})
print df
rater_id url rat2 rat1 desc
0 '001' a 2.5 3.0 sunny day
1 '002' a 4.5 1.0 sunshine
2 '001' b 1.5 4.0 rainy day
3 '002' b 3.5 3.0 rain
4 '001' c 5.0 5.0 foggy day
5 '002' d 3.5 1.0 snow
#aggregate
df = df.groupby(['url']).agg({'rat1':['mean', 'var'],
'rat2':['mean', 'var'],
'desc': ' '.join,
'rater_id': 'count'})
#reset multiindex in columns
df.columns = ['_'.join(col) for col in df.columns.values]
print df
rater_id_count rat2_mean rat2_var rat1_mean rat1_var \
url
a 2 3.5 2.0 2.0 2.0
b 2 2.5 2.0 3.5 0.5
c 1 5.0 NaN 5.0 NaN
d 1 3.5 NaN 1.0 NaN
desc_join
url
a sunny day sunshine
b rainy day rain
c foggy day
d snow
答案 1 :(得分:0)
我会做类似以下的事情
ids_url1 = ['id', 'rating_1(1)', 'rating_2(1)', 'rating_3(1)', 'description(1)']
ids_url2 = ['id', 'rating_1(2)', 'rating_2(2)', 'rating_3(2)', 'description(2)']
ids_url3 = ['id', 'rating_1(3)', 'rating_2(3)', 'rating_3(3)', 'description(3)']
df1 = pd.melt(df, id_vars=ids_url1, value_vars=['url1'])
df2 = pd.melt(df, id_vars=ids_url2, value_vars=['url2'])
df3 = pd.melt(df, id_vars=ids_url3, value_vars=['url3'])
df1.drop(axis=1, labels='variable', inplace=True)
df1.set_index(['value', 'id'], inplace=True)
df1.columns = ["rating_1", "rating_2", "rating_3", "description"]
df2.drop(axis=1, labels='variable', inplace=True)
df2.set_index(['value', 'id'], inplace=True)
df2.columns = ["rating_1", "rating_2", "rating_3", "description"]
df3.drop(axis=1, labels='variable', inplace=True)
df3.set_index(['value', 'id'], inplace=True)
df3.columns = ["rating_1", "rating_2", "rating_3", "description"]
dfn = pd.concat([df1,df2,df3], axis=0)
然后你可以根据需要做groupby
并连接结果
dfn.groupby(axis=0, level=0).mean()
rating_1 rating_2 rating_3
value
a 2.0 3.5 NaN
b 3.5 2.5 NaN
c 5.0 5.0 NaN
d 1.0 3.5 NaN
dfn.groupby(axis=0, level=0)['description'].apply(lambda x: " ".join(x))
value
a sunny day sunshine
b rainy day rain
c foggy day
d snow
Name: description, dtype: object