Python在不转换数据类型的情况下创建层次索引ItErrors

Python在不转换数据类型的情况下创建层次索引ItErrors,python,pandas,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_o

我有一个带有层次索引的数据帧

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
我看到熊猫变成了一个系列,一切都变成了一个漂浮物。dif.iloc[0]似乎也执行了相同的类型转换

使用

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


有更好的方法吗?

您可以使用namedtuples和字典理解赋值:

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(例如,电势:_平方和)创建链接键


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

您想对每一行做什么?例如,您可以使用
itertuples
,它将为您提供单个值的元组。我将参数传递给一组不同的函数,以计算更高级的统计信息(数据帧的行数比我显示的要多得多)。itertuples是一个很好的选择,但随后会失去索引。我可能会考虑速度问题,这样我可以保持代码的可维护性。请使用df.to_dict()使示例数据更易于导入。
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