我正在尝试对熊猫数据框中的特定列求和。我从数据框中的文本开始,给定特定的单词,然后将文本更改为数字,然后进行求和。
我首先创建一个示例数据框:
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。我在做什么错了?
答案 0 :(得分: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
有不同的索引:
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