我有两个数据帧:
df1 - 是一个数据透视表,其中包含列和行的总计,两者都具有默认名称"所有" df2 - 我通过指定值并使用与上面数据透视表中使用的索引和列名相同的手动创建的df。此表没有总计。
我需要将第一个数据帧乘以第二个数据帧中的值。我预计总数将返回NaNs,因为总数不会存在于第二个表中。
当我执行乘法时,我收到以下错误:
ValueError: cannot join with no level specified and no overlapping names
当我在虚拟数据帧上尝试相同时,它按预期工作:
import pandas as pd
import numpy as np
table1 = np.matrix([[10, 20, 30, 60],
[50, 60, 70, 180],
[90, 10, 10, 110],
[150, 90, 110, 350]])
df1 = pd.DataFrame(data = table1, index = ['One','Two','Three', 'All'], columns =['A', 'B','C', 'All'] )
print(df1)
table2 = np.matrix([[1.0, 2.0, 3.0],
[5.0, 6.0, 7.0],
[2.0, 1.0, 5.0]])
df2 = pd.DataFrame(data = table2, index = ['One','Two','Three'], columns =['A', 'B','C'] )
print(df2)
df3 = df1*df2
print(df3)
这给了我以下输出:
A B C All
One 10 20 30 60
Two 50 60 70 180
Three 90 10 10 110
All 150 90 110 350
A B C
One 1.00 2.00 3.00
Two 5.00 6.00 7.00
Three 2.00 1.00 5.00
A All B C
All nan nan nan nan
One 10.00 nan 40.00 90.00
Three 180.00 nan 10.00 50.00
Two 250.00 nan 360.00 490.00
因此,在视觉上,df1和df2之间的唯一区别是列和行的存在/不存在"所有"。
我认为我的虚拟数据帧和真实数据帧之间的唯一区别是真正的df1是使用pd.pivot_table方法创建的:
df1_real = pd.pivot_table(PY, values = ['Annual Pay'], index = ['PAR Rating'],
columns = ['CR Range'], aggfunc = [np.sum], margins = True)
我确实需要保留总数,因为我在其他计算中使用它们。
我确定有一种解决方法,但我真的想了解为什么相同的代码适用于不同大小的某些数据帧但不适用于其他数据帧。或者问题可能完全不同。
感谢您的阅读。我意识到这是一个很长的帖子..
答案 0 :(得分:2)
IIUC,
我的首选方法
您可以使用mul
方法传递fill_value
参数。在这种情况下,您需要一个值1
(乘法标识)来保留值不会丢失的数据帧中的值。
df1.mul(df2, fill_value=1)
A All B C
All 150.0 350.0 90.0 110.0
One 10.0 60.0 40.0 90.0
Three 180.0 110.0 10.0 50.0
Two 250.0 180.0 360.0 490.0
替代方法
您还可以接受np.nan
并使用后续combine_first
填写df1
(df1 * df2).combine_first(df1)
A All B C
All 150.0 350.0 90.0 110.0
One 10.0 60.0 40.0 90.0
Three 180.0 110.0 10.0 50.0
Two 250.0 180.0 360.0 490.0
答案 1 :(得分:1)
我真的很喜欢Pir的方法,这是我的:-)
df1.loc[df2.index,df2.columns]*=df2
df1
Out[293]:
A B C All
One 10.0 40.0 90.0 60
Two 250.0 360.0 490.0 180
Three 180.0 10.0 50.0 110
All 150.0 90.0 110.0 350
答案 2 :(得分:0)
@Wen,@ piRSquared,谢谢你的帮助。这就是我最终做的事情。可能有一个更优雅的解决方案,但这对我有用。
由于我能够将两个不同大小的虚拟数据帧相乘,我推断问题的大小并不大,但事实上其中一个数据帧是作为数据透视表创建的。不知何故,在此数据透视表中,标题未被识别,尽管在视觉上它们在那里。所以,我决定将数据透视表转换为常规数据帧。我采取的步骤:
使用上述同一线程中的解决方案清除列标题:pandas pivot table to data frame。
在此帖子中将我的第一列设置为以下建议的索引:How to remove index from a created Dataframe in Python?
这给了我一个与之前相同的数据框,但不再是数据透视表。
然后我能够将这两个数据帧相乘而没有任何问题。我使用了@Wen建议的方法,因为我喜欢它保留了结构。