旋转包含字符串的 Pandas 数据框 - “没有要聚合的数字类型”错误
Posted
技术标签:
【中文标题】旋转包含字符串的 Pandas 数据框 - “没有要聚合的数字类型”错误【英文标题】:Pivoting a Pandas Dataframe containing strings - 'No numeric types to aggregate' error 【发布时间】:2016-03-30 06:34:59 【问题描述】:关于这个错误有很多问题,但环顾四周后,我仍然无法找到/围绕解决方案。 我正在尝试使用字符串旋转数据框,以使一些行数据成为列,但到目前为止还没有解决。
我的 df 形状
<class 'pandas.core.frame.DataFrame'>
Int64Index: 515932 entries, 0 to 515931
Data columns (total 5 columns):
id 515932 non-null object
cc_contact_id 515932 non-null object
Network_Name 515932 non-null object
question 515932 non-null object
response_answer 515932 non-null object
dtypes: object(5)
memory usage: 23.6+ MB
示例格式
id contact_id question response_answer
16 137519 2206 State Ca
17 137520 2206 State Ca
18 137521 2206 State Ca
19 137522 2206 State Ca
20 137523 2208 City Lancaster
21 137524 2208 City Lancaster
22 137525 2208 City Lancaster
23 137526 2208 City Lancaster
24 137527 2208 Trip_End Location Home
25 137528 2208 Trip_End Location Home
26 137529 2208 Trip_End Location Home
27 137530 2208 Trip_End Location Home
我想转向什么
id contact_id State City Trip_End Location
16 137519 2206 Ca None None None
20 137523 2208 None Lancaster None None
24 137527 2208 None None None Home
etc. etc.
question 值成为列的位置,response_answer 在其对应列中,并保留 id
我尝试过的
unified_df = pd.DataFrame(unified_data, columns=target_table_headers, dtype=object)
pivot_table = unified_df.pivot_table('response_answer',['id','cc_contact_id'],'question')
# OR
pivot_table = unified_df.pivot_table('response_answer','question')
DataError:没有要聚合的数字类型
用字符串值旋转数据框的方法是什么?
【问题讨论】:
你想通过旋转字符串值来实现什么? 这些数据有问题。为什么同一个contact_id 会多次回答同一个问题。您是按contact_id 还是其他方式分组...什么?? 目标是最终创建一个用于 Tableau 的报告表;将数据放在可以回答更多问题的形式中。就数据而言,缺少可以添加的细节;多个 contact_id 来自多个调查 - 未列出这些调查 id 【参考方案1】:有几种方法。
1
df1 = df.groupby(["id","contact_id","Network_Name","question"])['response_answer'].aggregate(lambda x: x).unstack().reset_index()
df1.columns=df1.columns.tolist()
print (df1)
2
df1 = df.set_index(["id","contact_id","Network_Name","question"])['response_answer'].unstack().reset_index()
df1.columns=df1.columns.tolist()
print (df1)
3
df1 = df.groupby(["id","contact_id","Network_Name","question"])['response_answer'].aggregate('first').unstack().reset_index()
df1.columns=df1.columns.tolist()
print (df1)
4
df1 = df.pivot_table(index=["id","contact_id","Network_Name"], columns='question', values=['response_answer'], aggfunc='first')
df1.columns = df1.columns.droplevel()
df1 = df1.reset_index()
df1.columns=df1.columns.tolist()
print (df1)
同样的答案。
id contact_id Network_Name City State Trip_End_Location
0 16 137519 2206 None Ca None
1 17 137520 2206 None Ca None
2 18 137521 2206 None Ca None
3 19 137522 2206 None Ca None
4 20 137523 2208 Lancaster None None
5 21 137524 2208 Lancaster None None
6 22 137525 2208 Lancaster None None
7 23 137526 2208 Lancaster None None
8 24 137527 2208 None None Home
9 25 137528 2208 None None Home
10 26 137529 2208 None None Home
11 27 137530 2208 None None Home
【讨论】:
嗨,你能帮我理解 aggfunc='first' 是什么(以第四种方式出现)吗?还有像“第一”这样的聚合类型吗?【参考方案2】:pivot_table
中的默认aggfunc
是np.sum
,它不知道如何处理字符串,并且您还没有指出索引应该是正确的。尝试类似:
pivot_table = unified_df.pivot_table(index=['id', 'contact_id'],
columns='question',
values='response_answer',
aggfunc=lambda x: ' '.join(x))
这显式地为每个 id, contact_id
对设置一行,并在 question
上旋转一组 response_answer
值。 aggfunc
只是确保如果您对原始数据中的同一个问题有多个答案,我们只需将它们与空格连接在一起。 pivot_table
的语法可能因您的 pandas 版本而异。
这是一个简单的例子:
In [24]: import pandas as pd
In [25]: import random
In [26]: df = pd.DataFrame('id':[100*random.randint(10, 50) for _ in range(100)], 'question': [str(random.randint(0,3)) for _ in range(100)], 'response': [str(random.randint(100,120)) for _ in range(100)])
In [27]: df.head()
Out[27]:
id question response
0 3100 1 116
1 4500 2 113
2 5000 1 120
3 3900 2 103
4 4300 0 117
In [28]: df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 100 entries, 0 to 99
Data columns (total 3 columns):
id 100 non-null int64
question 100 non-null object
response 100 non-null object
dtypes: int64(1), object(2)
memory usage: 3.1+ KB
In [29]: df.pivot_table(index='id', columns='question', values='response', aggfunc=lambda x: ' '.join(x)).head()
Out[29]:
question 0 1 2 3
id
1000 110 120 NaN 100 NaN
1100 NaN 106 108 104 NaN
1200 104 113 119 NaN 101
1300 102 NaN 116 108 120
1400 NaN NaN 116 NaN
【讨论】:
索引应该是id,因为它是SELECT Row_number() OVER() AS id创建的唯一标识符,给每一行一个唯一的int。如果我在 contact_id 之外添加了调查 id,那么这些将是唯一的,我可以省去生成的 id 您可以以任何您认为与您想要的聚合级别相匹配的方式来索引枢轴。只需将index
参数设置为您想要的规范。
此问题的索引是 id 和 contact_id 然后我希望将 response_answer 字符串列在数据框值中,在它们的透视问题列标题下,以从更高级别的问题创建 SQL 表可能是,Pandas 是使用字符串数据透视表的最佳 Python 工具吗?看来可能是……
这正是答案中第一个 sn-p 所做的事情......试一试,看看它是否满足你的愿望。
运行良好的最终解决方案(我添加了screening_id基本上形成了contact_id和screening_id的唯一复合索引):pivot_table = Unified_df.pivot_table(index=['id','contact_id', 'screening_id'], columns='question', values='response_answer', aggfunc=lambda x: ' '.join(x))以上是关于旋转包含字符串的 Pandas 数据框 - “没有要聚合的数字类型”错误的主要内容,如果未能解决你的问题,请参考以下文章
Pandas:使用 MultiIndex 旋转数据框时出现 ValueError