【问题标题】:grouped pandas DataFrames: how do I apply scipy.stats.sem to them?分组 pandas DataFrames:如何将 scipy.stats.sem 应用于它们?
【发布时间】:2012-07-04 11:52:27
【问题描述】:

我知道我可以通过执行以下操作来应用 numpy 方法:

dataListDataFrames 的列表(相同的列/行)。

testDF = (concat(dataList, axis=1, keys=range(len(dataList)))
        .swaplevel(0, 1, axis=1)
        .sortlevel(axis=1)
        .groupby(level=0, axis=1))

testDF.aggregate(numpy.mean)
testDF.aggregate(numpy.var)

等等。但是,如果我想计算均值 (sem) 的标准误怎么办?

我试过了:

testDF.aggregate(scipy.stats.sem)

但它给出了一个令人困惑的错误。有人知道怎么做吗? scipy.stats 方法有何不同?

这里有一些代码可以为我重现错误:

from scipy import stats as st
import pandas
import numpy as np
df_list = []
for ii in range(30):
    df_list.append(pandas.DataFrame(np.random.rand(600, 10), 
    columns = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']))

testDF = (pandas.concat(df_list, axis=1, keys=range(len(df_list)))
         .swaplevel(0, 1, axis=1)
         .sortlevel(axis=1)
         .groupby(level=0, axis=1))

testDF.aggregate(st.sem)

这是错误信息:

---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-1-184cee8fb2ce> in <module>()
     12          .groupby(level=0, axis=1))
     13 
---> 14 testDF.aggregate(st.sem)

/Library/Frameworks/EPD64.framework/Versions/7.3/lib/python2.7/site-packages/pandas/core/groupby.py in aggregate(self, arg, *args, **kwargs)
   1177                 return self._python_agg_general(arg, *args, **kwargs)
   1178             else:
-> 1179                 result = self._aggregate_generic(arg, *args, **kwargs)
   1180 
   1181         if not self.as_index:

/Library/Frameworks/EPD64.framework/Versions/7.3/lib/python2.7/site-packages/pandas/core/groupby.py in _aggregate_generic(self, func, *args, **kwargs)
   1248             else:
   1249                 result = DataFrame(result, index=obj.index,
-> 1250                                    columns=result_index)
   1251         else:
   1252             result = DataFrame(result)

/Library/Frameworks/EPD64.framework/Versions/7.3/lib/python2.7/site-packages/pandas/core/frame.py in __init__(self, data, index, columns, dtype, copy)
    300             mgr = self._init_mgr(data, index, columns, dtype=dtype, copy=copy)
    301         elif isinstance(data, dict):
--> 302             mgr = self._init_dict(data, index, columns, dtype=dtype)
    303         elif isinstance(data, ma.MaskedArray):
    304             mask = ma.getmaskarray(data)

/Library/Frameworks/EPD64.framework/Versions/7.3/lib/python2.7/site-packages/pandas/core/frame.py in _init_dict(self, data, index, columns, dtype)
    389 
    390         # consolidate for now
--> 391         mgr = BlockManager(blocks, axes)
    392         return mgr.consolidate()
    393 

/Library/Frameworks/EPD64.framework/Versions/7.3/lib/python2.7/site-packages/pandas/core/internals.py in __init__(self, blocks, axes, do_integrity_check)
    329 
    330         if do_integrity_check:
--> 331             self._verify_integrity()
    332 
    333     def __nonzero__(self):

/Library/Frameworks/EPD64.framework/Versions/7.3/lib/python2.7/site-packages/pandas/core/internals.py in _verify_integrity(self)
    404         mgr_shape = self.shape
    405         for block in self.blocks:
--> 406             assert(block.values.shape[1:] == mgr_shape[1:])
    407         tot_items = sum(len(x.items) for x in self.blocks)
    408         assert(len(self.items) == tot_items)

AssertionError:

【问题讨论】:

  • 您能否复制并粘贴实际的错误消息,或者更好的是重现错误的小代码示例?当我尝试时它对我有用。
  • @DSM:我在原始问题中添加了错误消息。请注意,我可以在完全相同的 DataFrame 上执行 numpy 方法而不会出现问题。
  • 我现在可以重现错误,所以让我们看看.. 可能我的测试数据框太简单了。
  • 更多信息:dataList 由 30 个 DataFrames 组成,这些 DataFrames 是从 csv 文件中读取的(1 个 csv 文件 = 1 个 DataFrame)。每个 csv 文件有 10 列和 600 行。

标签: python numpy statistics scipy pandas


【解决方案1】:

更新答案:

看来我可以使用我的各种库的工作版本来复制它。稍后我会检查我的家庭版本,看看这些功能的文档是否存在差异。

与此同时,使用您的确切编辑版本,以下内容对我有用:

In [35]: testDF.aggregate(lambda x: st.sem(x, axis=None))
Out[35]:
<class 'pandas.core.frame.DataFrame'>
Int64Index: 600 entries, 0 to 599
Data columns:
A    600  non-null values
B    600  non-null values
C    600  non-null values
D    600  non-null values
E    600  non-null values
F    600  non-null values
G    600  non-null values
H    600  non-null values
I    600  non-null values
J    600  non-null values
dtypes: float64(10)

这让我怀疑它与sem() 轴约定有关。它默认为 0,最终映射到的 Pandas 对象可能有一个奇怪的第 0 轴或其他东西。当我使用选项axis=None 时,它会分解它所应用的对象,这使它起作用。

作为一个健全的检查,我这样做了,它也有效:

In [37]: testDF.aggregate(lambda x: st.sem(x, axis=1))
Out[37]:
<class 'pandas.core.frame.DataFrame'>
Int64Index: 600 entries, 0 to 599
Data columns:
A    600  non-null values
B    600  non-null values
C    600  non-null values
D    600  non-null values
E    600  non-null values
F    600  non-null values
G    600  non-null values
H    600  non-null values
I    600  non-null values
J    600  non-null values
dtypes: float64(10)

但您应该检查以确保这实际上是您想要的 SEM 值,可能是在一些较小的示例数据上。

旧答案: 这可能与 scipy.stats 的模块问题有关吗?当我使用这个模块时,我必须将它称为from scipy import stats as st 或类似的名称。 import scipy.stats 不起作用,调用 import scipy; scipy.stats.sem 会给出一个错误,指出不存在名为“stats”的模块。

Pandas 似乎根本没有找到该功能。我认为应该改进错误消息,因为这并不明显。

>>> from scipy import stats as st
>>> import pandas
>>> import numpy as np
>>> df_list = []
>>> for ii in range(10):
...     df_list.append(pandas.DataFrame(np.random.rand(10,3), 
...     columns = ['A', 'B', 'C']))
... 
>>> df_list
# Suppressed the output cause it was big.

>>> testDF = (pandas.concat(df_list, axis=1, keys=range(len(df_list)))
...     .swaplevel(0, 1, axis=1)
...     .sortlevel(axis=1)
...     .groupby(level=0, axis=1))
>>> testDF
<pandas.core.groupby.DataFrameGroupBy object at 0x38524d0>
>>> testDF.aggregate(np.mean)
key_0         A         B         C
0      0.660324  0.408377  0.374681
1      0.459768  0.345093  0.432542
2      0.498985  0.443794  0.524327
3      0.605572  0.563768  0.558702
4      0.561849  0.488395  0.592399
5      0.466505  0.433560  0.408804
6      0.561591  0.630218  0.543970
7      0.423443  0.413819  0.486188
8      0.514279  0.479214  0.534309
9      0.479820  0.506666  0.449543
>>> testDF.aggregate(np.var)
key_0         A         B         C
0      0.093908  0.095746  0.055405
1      0.075834  0.077010  0.053406
2      0.094680  0.092272  0.095552
3      0.105740  0.126101  0.099316
4      0.087073  0.087461  0.111522
5      0.105696  0.110915  0.096959
6      0.082860  0.026521  0.075242
7      0.100512  0.051899  0.060778
8      0.105198  0.100027  0.097651
9      0.082184  0.060460  0.121344
>>> testDF.aggregate(st.sem)
          A         B         C
0  0.089278  0.087590  0.095891
1  0.088552  0.081365  0.098071
2  0.087968  0.116361  0.076837
3  0.110369  0.087563  0.096460
4  0.101328  0.111676  0.046567
5  0.085044  0.099631  0.091284
6  0.113337  0.076880  0.097620
7  0.087243  0.087664  0.118925
8  0.080569  0.068447  0.106481
9  0.110658  0.071082  0.084928

似乎对我有用。

【讨论】:

  • 我开始怀疑我的安装是否有问题。我使用您的代码版本编辑了我的原始问题,该版本为我重现了错误(并且更能代表我的数据集)。
  • 代码中的第一个 AssertionError 表明您没有运行您发布的编辑版本。它在线上令人窒息,@ 987654329@,这看起来像你的老问题......只导入 SciPy 然后尝试使用 scipy.stats.sem,这是行不通的。您能弄清楚为什么它向我们显示代码 test = testDF.aggregate(sp.stats.sem) 的错误,而不是不涉及以这种方式导入 SciPy 的新编辑版本吗?我怀疑您运行的编辑版本错误。
  • 我编辑了一些似乎有效的东西。看起来这是sem() 的新版本的问题,它的默认轴约定与旧版本不同。我现在的猜测是,任何被 aggregate() 函数击中的 Pandas 切片/组的东西都有一个坏的(可能是单例或其他东西)第 0 维,并且数组需要被展平才能工作。
  • 就是这样!我对照我的数据检查了它,axis=1 方法正确计算了sem()。奇怪的是,我之前用于计算 sem 的方法的结果 std / sqrt(# replicates)sem() 结果略有不同,但我们只是在谈论最大约 4e-11 的差异。估计是圆的谢谢老兄。
猜你喜欢
  • 2017-06-15
  • 2015-06-02
  • 2021-01-07
  • 1970-01-01
  • 1970-01-01
  • 2013-06-06
  • 2014-08-30
  • 2018-03-06
  • 2013-02-09
相关资源
最近更新 更多