我有一个带有分层索引的数据框。
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
我看到pandas转换为一个系列,一切都变成了float64。 dif.iloc [0]似乎也预先形成了相同的类型转换。
使用
for i in df.index:
row = df[df.sn == i]
row.dtypes
我仍然有一个数据框,它似乎工作得很好(假设我的索引是唯一的),但我认为这样效率要低得多。
有更好的方法吗?
答案 0 :(得分: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创建链式密钥(例如,潜在的:_sum_of_squares)。
由于这些行现在是元组,因此无法更改数据(这可能是您想要的)。