我有一个带有分层索引的数据框。
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)。
由于这些行现在是元组,因此无法更改数据(这可能是您想要的)。