在Python中用pandas对数据帧进行装箱

在Python中用pandas对数据帧进行装箱,python,numpy,pandas,Python,Numpy,Pandas,给定熊猫中的以下数据帧: import numpy as np df = pandas.DataFrame({"a": np.random.random(100), "b": np.random.random(100), "id": np.arange(100)}) 如果id是由a和b值组成的每个点的id,我如何将a和b放入一组指定的存储箱中(这样我就可以在每个存储箱中取a和b的中值/平均值)

给定熊猫中的以下数据帧:

import numpy as np
df = pandas.DataFrame({"a": np.random.random(100), "b": np.random.random(100), "id": np.arange(100)})
如果
id
是由
a
b
值组成的每个点的id,我如何将
a
b
放入一组指定的存储箱中(这样我就可以在每个存储箱中取
a
b
的中值/平均值)<对于
df
中的任何给定行,
a
b
(或两者)可能具有
NaN
值。谢谢

这里有一个更好的例子,使用Joe Kington的解决方案和更现实的df。我不确定的是如何访问下面每个df.a组的df.b元素:

a = np.random.random(20)
df = pandas.DataFrame({"a": a, "b": a + 10})
# bins for df.a
bins = np.linspace(0, 1, 10)
# bin df according to a
groups = df.groupby(np.digitize(df.a,bins))
# Get the mean of a in each group
print groups.mean()
## But how to get the mean of b for each group of a?
# ...

可能有一种更有效的方法(我感觉熊猫。交叉表在这里很有用),但我会这样做:

import numpy as np
import pandas

df = pandas.DataFrame({"a": np.random.random(100),
                       "b": np.random.random(100),
                       "id": np.arange(100)})

# Bin the data frame by "a" with 10 bins...
bins = np.linspace(df.a.min(), df.a.max(), 10)
groups = df.groupby(np.digitize(df.a, bins))

# Get the mean of each bin:
print groups.mean() # Also could do "groups.aggregate(np.mean)"

# Similarly, the median:
print groups.median()

# Apply some arbitrary function to aggregate binned data
print groups.aggregate(lambda x: np.mean(x[x > 0.5]))

编辑:由于OP特别要求使用由
a
中的值组合而成的
b
的方法,所以只需这样做即可

groups.mean().b
此外,如果您希望索引看起来更好(例如,将间隔显示为索引),就像@bdiamante的示例中那样,请使用
pandas.cut
而不是
numpy.digitized
。(比达曼特的功劳。我没有意识到熊猫。切的存在。)

这导致:

a
(0.00186, 0.111]    10.421839
(0.111, 0.22]       10.427540
(0.22, 0.33]        10.538932
(0.33, 0.439]       10.445085
(0.439, 0.548]      10.313612
(0.548, 0.658]      10.319387
(0.658, 0.767]      10.367444
(0.767, 0.876]      10.469655
(0.876, 0.986]      10.571008
Name: b

不是100%确定这是否是你想要的,但以下是我认为你想要的:

In [144]: df = DataFrame({"a": np.random.random(100), "b": np.random.random(100), "id":   np.arange(100)})

In [145]: bins = [0, .25, .5, .75, 1]

In [146]: a_bins = df.a.groupby(cut(df.a,bins))

In [147]: b_bins = df.b.groupby(cut(df.b,bins))

In [148]: a_bins.agg([mean,median])
Out[148]:
                 mean    median
a
(0, 0.25]    0.124173  0.114613
(0.25, 0.5]  0.367703  0.358866
(0.5, 0.75]  0.624251  0.626730
(0.75, 1]    0.875395  0.869843

In [149]: b_bins.agg([mean,median])
Out[149]:
                 mean    median
b
(0, 0.25]    0.147936  0.166900
(0.25, 0.5]  0.394918  0.386729
(0.5, 0.75]  0.636111  0.655247
(0.75, 1]    0.851227  0.838805

当然,我不知道你在想什么样的箱子,所以你必须根据你的情况换掉我的。

乔·金顿的回答非常有用,但是,我注意到它并没有把所有的数据都装进箱子。它实际上用a=a.min()省去了该行。将
组相加。size()
得到99而不是100

为了保证所有数据都已装箱,只需传入要剪切的箱子数量(),该函数将自动将第一个[最后一个]箱子填充0.1%,以确保包含所有数据

df = pandas.DataFrame({"a": np.random.random(100), 
                    "b": np.random.random(100) + 10})

# Bin the data frame by "a" with 10 bins...
groups = df.groupby(pandas.cut(df.a, 10))

# Get the mean of b, binned by the values in a
print(groups.mean().b)
在本例中,将groups.size()相加得到100


我知道对于这个特殊的问题,这是一个挑剔的问题,但是对于我试图解决的一个类似的问题,获得正确的答案是至关重要的。

如果你不必坚持分组,你可以使用
scipy.stats.binned\u statistic

from scipy.stats import binned_statistic

means = binned_statistic(df.a, df.b, bins=np.linspace(min(df.a), max(df.a), 10))

美好的我以为OP想把“b”归为“a”,但现在回想起来,你的答案可能就是他们想要的。我将保留我的答案,因为我们的答案略有不同。也许值得一提的是,它是
pandas.Dataframe({..})
a_bins.agg([numpy.mean,numpy.median])
优秀而优雅!正是我想要的。根本不需要对数据帧进行排序。如果要根据组访问
b
值,该怎么办
groups.mean()
只为
a
提供了平均值,我相信。@user248237dfsf-不,它为
a
b
提供了平均值(或者更确切地说,它为
a
中的值提供了
b
的平均值,这正是我认为您所要求的)。
groups.mean()
返回一个
数据帧
,因此您可以执行
组.mean()[“b”]
来访问
a
绑定的
b
的方法。
from scipy.stats import binned_statistic

means = binned_statistic(df.a, df.b, bins=np.linspace(min(df.a), max(df.a), 10))