以下所有内容似乎都适用于迭代熊猫系列的元素。我相信有更多的方法可以做到这一点。有什么区别,哪种方法最好?
import pandas
arr = pandas.Series([1, 1, 1, 2, 2, 2, 3, 3])
# 1
for el in arr:
print(el)
# 2
for _, el in arr.iteritems():
print(el)
# 3
for el in arr.array:
print(el)
# 4
for el in arr.values:
print(el)
# 5
for i in range(len(arr)):
print(arr.iloc[i])
Run Code Online (Sandbox Code Playgroud)
tdy*_*tdy 14
在Pandas 中迭代是一种反模式,通常可以通过向量化、应用、聚合、转换或cythonizing来避免。
但是,如果绝对需要系列迭代,则性能将取决于 dtype 和索引:
| 指数 | 如果numpy dtype最快 | 如果pandas dtype最快 | 惯用语 |
|---|---|---|---|
| 不需要 | in s.to_numpy() |
in s.array |
in s |
| 默认 | in enumerate(s.to_numpy()) |
in enumerate(s.array) |
in s.items() |
| 风俗 | in zip(s.index, s.to_numpy()) |
in s.items() |
in s.items() |
s.to_numpy()如果 Series 是python 或numpy dtype ,迭代底层 numpy ndarray 通常是最快的:
for el in s.to_numpy(): # if dtype is datetime, int, float, str, string
Run Code Online (Sandbox Code Playgroud)
要访问索引,实际上最快的是enumerate()或zip()numpy ndarray:
for i, el in enumerate(s.to_numpy()): # if default range index
Run Code Online (Sandbox Code Playgroud)
for i, el in zip(s.index, s.to_numpy()): # if custom index
Run Code Online (Sandbox Code Playgroud)
两者都比惯用的s.items()/快s.iteritems():
微优化,切换到s.tolist()更短int/ float/str系列:
for el in s.to_numpy(): # if >100K elements
Run Code Online (Sandbox Code Playgroud)
for el in s.tolist(): # to micro-optimize if <100K elements
Run Code Online (Sandbox Code Playgroud)
警告:不要使用,list(s)因为它不使用编译代码,这会使它变慢。
s.array或s.items()Pandas 扩展 dtypes包含额外的(元)数据,例如:
| 大熊猫数据类型 | 内容 |
|---|---|
Categorical |
2个阵列 |
DatetimeTZ |
数组 + 时区元数据 |
Interval |
2个阵列 |
Period |
数组 + 频率元数据 |
| ... | ... |
将这些扩展数组转换为 numpy “可能很昂贵”,因为它可能涉及复制/强制数据,因此:
如果 Series 是Pandas 扩展 dtype,则迭代底层 Pandas 数组通常是最快的:
for el in s.array: # if dtype is pandas-only extension
Run Code Online (Sandbox Code Playgroud)
例如,有 ~100 个唯一Categorical值:
要访问索引,s.items() pandas dtypes的惯用语非常快:
for i, el in s.items(): # if need index for pandas-only dtype
Run Code Online (Sandbox Code Playgroud)
要进行微优化,请切换到enumerate()默认索引Categorical数组的稍微快一点:
for i, el in enumerate(s.array): # to micro-optimize Categorical dtype if need default range index
Run Code Online (Sandbox Code Playgroud)
s.to_numpy()得到根本numpy的ndarrays.array获得的潜在大熊猫阵列你永远不应该修改你正在迭代的东西。这不能保证在所有情况下都有效。根据数据类型,迭代器返回一个副本而不是一个视图,写入它没有任何效果!
尽可能避免手动迭代:
向量化、(布尔)索引等。
应用函数,例如:
注意:这些是不是尽管常见的误解vectorizations。
规格:的ThinkPad X1极端创3(核心i7-10850H 2.70GHz,32GB DDR4 2933MHz)
版本:python==3.9.2,pandas==1.3.1,numpy==1.20.2
测试数据:系列生成代码段中的代码
'''
Note: This is python code in a js snippet, so "run code snippet" will not work.
The snippet is just to avoid cluttering the main post with supplemental code.
'''
import pandas as pd
import numpy as np
int_series = pd.Series(np.random.randint(1000000000, size=n))
float_series = pd.Series(np.random.randn(size=n))
floatnan_series = pd.Series(np.random.choice([np.nan, np.inf]*n + np.random.randn(n).tolist(), size=n))
str_series = pd.Series(np.random.randint(10000000000000000, size=n)).astype(str)
string_series = pd.Series(np.random.randint(10000000000000000, size=n)).astype('string')
datetime_series = pd.Series(np.random.choice(pd.date_range('2000-01-01', '2021-01-01'), size=n))
datetimetz_series = pd.Series(np.random.choice(pd.date_range('2000-01-01', '2021-01-01', tz='CET'), size=n))
categorical_series = pd.Series(np.random.randint(100, size=n)).astype('category')
interval_series = pd.Series(pd.arrays.IntervalArray.from_arrays(-np.random.random(size=n), np.random.random(size=n)))
period_series = pd.Series(pd.period_range(end='2021-01-01', periods=n, freq='s'))Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
624 次 |
| 最近记录: |