汇总熊猫数据框中的特定列

时间:2019-08-08 14:19:49

标签: python pandas dataframe

我正在尝试对熊猫数据框中的特定列求和。我从数据框中的文本开始,给定特定的单词,然后将文本更改为数字,然后进行求和。

我首先创建一个示例数据框:

import pandas as pd

df = pd.DataFrame({'a': [1,'produces','produces','understands','produces'], 'b' : [2,'','produces','understands','understands'], 'c' : [3,'','','understands','']})
transposed_df = df.transpose()
transposed_df

输出:

   0         1         2            3            4
a  1  produces  produces  understands     produces
b  2            produces  understands  understands
c  3                      understands             

这一切都很好,而且我期望如此。然后,我将相关文本更改为整数,并创建一个(主要是)整数的数据框。

measure1 = transposed_df.iloc[:,[0,1,2]].replace('produces',1)
measure2 = transposed_df.iloc[:,[0,3]].replace('understands',1)
measure3 = transposed_df.iloc[:,[0,4]].replace('produces',1)

measures = [measure1, measure2, measure3]

from functools import reduce
counter = reduce (lambda left, right: pd.merge(left,right), measures)

counter

输出:

   0  1  2  3            4
0  1  1  1  1            1
1  2     1  1  understands
2  3        1             

这是我的期望。

然后我尝试对每一行的第1列和第2列求和,然后将其重新添加到transposed_df

transposed_df['first']=counter.iloc[:,[1,2]].sum(axis=1)
transposed_df

输出:

   0         1         2            3            4  first
a  1  produces  produces  understands     produces    NaN
b  2            produces  understands  understands    NaN
c  3                      understands                 NaN

我希望最后一列是2,1,0。我在做什么错了?

1 个答案:

答案 0 :(得分:1)

存在两个问题:求和与具有不同索引的列的插入。

1)求和

您的df类型为objects(所有字符串,包括空字符串)。数据框counter也是混合类型(整数和字符串):

counter.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 3 entries, 0 to 2
Data columns (total 5 columns):
0    3 non-null int64
1    3 non-null object
2    3 non-null object
3    3 non-null int64
4    3 non-null object
dtypes: int64(2), object(3)

请记住:

  

具有混合类型的列与对象dtype一起存储。 see dtypes

因此,尽管counters的第一行包含两个整数,但它们属于object类型的系列(列),而熊猫不喜欢将它们加起来(显然,您使用的是熊猫低于0.22.0的版本,在更高版本中,结果为0.0,默认值为min_count=0,请参见sum)。您可以通过

看到它
counter.iloc[:,[1,2]].applymap(type)

               1              2
0  <class 'int'>  <class 'int'>
1  <class 'str'>  <class 'int'>
2  <class 'str'>  <class 'str'>

因此解决方案是在可能的情况下将对象显式转换为数值(即整行由整数组成,而不是空字符串和整数):

counter.iloc[:,[1,2]].apply(lambda x: sum(pd.to_numeric(x)), axis=1)

结果:

0    2.0
1    NaN
2    NaN


2)列插入

有不同的索引:

counter.index
# Int64Index([0, 1, 2], dtype='int64')
transposed_df.index
# Index(['a', 'b', 'c'], dtype='object')

因此,使用您的方法可以获得所有Nans。最简单的方法是只插入系列的值,而不是系列本身(其中熊猫将索引对齐:

transposed_df['first'] = counter.iloc[:,[1,2]].apply(lambda x: sum(pd.to_numeric(x)), axis=1).to_list()

结果:

   0         1         2            3            4  first
a  1  produces  produces  understands     produces    2.0
b  2            produces  understands  understands    NaN
c  3                      understands                 NaN