旋转包含字符串的 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 中的默认aggfuncnp.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 合并、缩放和旋转长格式和宽格式数据帧

Pandas:使用 MultiIndex 旋转数据框时出现 ValueError

如何在 Pandas 中正确旋转或重塑时间序列数据框?

快速搜索 Pandas 数据框列

如何从 Pandas 数据框中过滤包含字符串模式的行 [重复]

如何在整个 Pandas 数据框中搜索字符串并获取包含它的列的名称?