Python Pandas 分层索引迭代行而不转换数据类型



我有一个带有分层索引的数据框。

In [57]: df = pd.DataFrame({('potential', 'sum'): {0: 8.0498308000000005, 1: 10901.381148799968}, ('datapoint_num', 'min'): {0: 1, 1: 6}, ('step_index', 'si'): {0: 1, 1: 6}, ('datapoint_num', 'N'): {0: 5, 1: 8600}, ('potential', 'sum_of_squares'): {0: 12.959955292916959, 1: 13910.219889184529}, ('datapoint_num', 'max'): {0: 5, 1: 8605}})
In [58]: df
Out[58]: 
   datapoint_num                potential                  step_index
               N   max  min           sum  sum_of_squares          si
0              5     5    1      8.049831       12.959955           1
1           8600  8605    6  10901.381149    13910.219889           6

我用它来计算流数据的一堆汇总统计数据。我想在不更改数据类型的情况下迭代其行。其初始数据类型为:

In [43]: df.dtypes
step_index       si                  int64
datapoint_num    max                 int64
                 N                   int64
                 min                 int64
potential        sum_of_squares    float64
                 sum               float64
sn                                   int64

如果我打电话

for sn, row in df.iterrows:
    row.dtype

我看到熊猫转换为一个系列,一切都变成了浮点数64。 dif.iloc[0] 似乎也进行了相同类型的转换。

for i in df.index:
    row = df[df.sn == i]
    row.dtypes

我仍然有一个数据帧,它似乎工作得很好(假设我的索引是唯一的),但我认为效率要低得多。

有没有更好的方法可以做到这一点?

您可以使用命名元组和字典理解赋值:

Row = namedtuple('Row', ['N', 'max', 'min', 'sum', 'sum_of_squares', 'si'])
rows = {i: Row(*df.iloc[i, :]) for i in df.index}
>>> rows
{0: Row(N=5.0, max=5.0, min=1.0, sum=8.0498308000000005, sum_of_squares=12.959955292916959, si=1.0),
 1: Row(N=8600.0, max=8605.0, min=6.0, sum=10901.381148799968, sum_of_squares=13910.219889184529, si=6.0)}
>>> type(rows[0].min)
numpy.float64

我注意到导入的数据类型也不是您所期望的,所以我不确定这将如何满足您的需求:

df = pd.DataFrame({('potential', 'sum'): {0: 8.0498308000000005, 1: 10901.381148799968}, ('datapoint_num', 'min'): {0: 1, 1: 6}, ('step_index', 'si'): {0: 1, 1: 6}, ('datapoint_num', 'N'): {0: 5, 1: 8600}, ('potential', 'sum_of_squares'): {0: 12.959955292916959, 1: 13910.219889184529}, ('datapoint_num', 'max'): {0: 5, 1: 8605}})
>>> df.iloc[0, 2]
1.0
>>> type(df.iloc[0, 2])
numpy.float64

您可能期待一个 int64。

此外,因为这似乎是针对特定需求的,所以它应该有效,因为子级别是唯一的(例如,仅在"max"上存在)。 更一般地说,可以通过 level0:_level1 创建链式密钥(例如 potential:_sum_of_squares)。

由于这些行现在是元组,因此无法更改数据(这可能是您想要的)。

最新更新