应用于 pandas DataFrame 的 Cythonizing 字符串数组比较函数
Cythonizing string array comparison function to be applied to pandas DataFrame
我刚刚开始使用 Cython,希望能就如何处理此过程提供一些建议。我发现我的代码中存在速度瓶颈,想要优化特定操作的性能。
我有一个 pandas DataFrame trades
看起来像这样:
Codes Price Size
Time
2015-02-24 15:30:01-05:00 R6,IS 11.6100 100
2015-02-24 15:30:01-05:00 R6,IS 11.6100 100
2015-02-24 15:30:01-05:00 R6,IS 11.6100 100
2015-02-24 15:30:01-05:00 11.6100 375
2015-02-24 15:30:01-05:00 R6,IS 11.6100 100
... ... ... ...
2015-02-24 15:59:55-05:00 R6,IS 11.5850 100
2015-02-24 15:59:55-05:00 R6,IS 11.5800 200
2015-02-24 15:59:55-05:00 T 11.5850 100
2015-02-24 15:59:56-05:00 R6,IS 11.5800 175
2015-02-24 15:59:56-05:00 R6,IS 11.5800 225
[5187 rows x 3 columns]
我有一个名为 codes
的 numpy
数组:
array(['4', 'AP', 'CM', 'BP', 'FA', 'FI', 'NC', 'ND', 'NI', 'NO', 'PT',
'PV', 'PX', 'SD', 'WO'],
dtype='|S2')
我需要过滤 trades
,如果 codes
中的任何值包含在 trades['Codes']
中,则该行被排除。目前我正在这样做:
ix = trades.Codes.str.split(',').apply(lambda cs: not any(c in excludes for c in cs))
trades = trades[ix]
但是,这太慢了,我需要让它更快。我想使用 cython(如 here or maybe numba 所述,看来 cython 是更好的选择。
我基本上需要这样的功能:
def isinCodes(codes_array1, codes_array2):
for x in codes_array1:
for y in codes_array2:
if x == y: return True
return False
cythonizing 时需要使用哪些类型?
这很容易向量化。
构造一个框架,我拿了100000*你的例子,1M行。
In [76]: df2.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 1000000 entries, 0 to 9
Data columns (total 4 columns):
date 1000000 non-null datetime64[ns]
code 900000 non-null object
price 1000000 non-null float64
volume 1000000 non-null int64
dtypes: datetime64[ns](1), float64(1), int64(1), object(1)
memory usage: 38.1+ MB
In [77]: df2.head()
Out[77]:
date code price volume
0 2015-02-24 20:30:01 R6,IS 11.61 100
1 2015-02-24 20:30:01 R6,IS 11.61 100
2 2015-02-24 20:30:01 R6,IS 11.61 100
3 2015-02-24 20:30:01 NaN 11.61 375
4 2015-02-24 20:30:01 R6,IS 11.61 100
此代码实际上是:df2.code.str.split(',',expand=True)
,但 ATM 存在性能问题,将在 0.16.2 中修复,请参阅 here。所以这段代码以非常高效的方式进行拆分。
In [78]: result = DataFrame([ [ s ] if not isinstance(s, list) else s for s in df2.code.str.split(',') ],columns=['A','B'])
In [79]: %timeit DataFrame([ [ s ] if not isinstance(s, list) else s for s in df2.code.str.split(',') ],columns=['A','B'])
1 loops, best of 3: 941 ms per loop
In [80]: result.head()
Out[80]:
A B
0 R6 IS
1 R6 IS
2 R6 IS
3 NaN None
4 R6 IS
我在isin
的最后加了'T'
In [81]: isin
Out[81]:
['4',
'AP',
'CM',
'BP',
'FA',
'FI',
'NC',
'ND',
'NI',
'NO',
'PT',
'PV',
'PX',
'SD',
'WO',
'T']
结果
In [82]: df2[(result.A.isin(isin) | result.A.isin(isin))].info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 100000 entries, 7 to 7
Data columns (total 4 columns):
date 100000 non-null datetime64[ns]
code 100000 non-null object
price 100000 non-null float64
volume 100000 non-null int64
dtypes: datetime64[ns](1), float64(1), int64(1), object(1)
memory usage: 3.8+ MB
In [83]: df2[(result.A.isin(isin) | result.A.isin(isin))].head()
Out[83]:
date code price volume
7 2015-02-24 20:59:55 T 11.585 100
7 2015-02-24 20:59:55 T 11.585 100
7 2015-02-24 20:59:55 T 11.585 100
7 2015-02-24 20:59:55 T 11.585 100
7 2015-02-24 20:59:55 T 11.585 100
实际操作比拆分到这里要快很多
In [84]: %timeit df2[(result.A.isin(isin) | result.A.isin(isin))]
10 loops, best of 3: 106 ms per loop
我刚刚开始使用 Cython,希望能就如何处理此过程提供一些建议。我发现我的代码中存在速度瓶颈,想要优化特定操作的性能。
我有一个 pandas DataFrame trades
看起来像这样:
Codes Price Size
Time
2015-02-24 15:30:01-05:00 R6,IS 11.6100 100
2015-02-24 15:30:01-05:00 R6,IS 11.6100 100
2015-02-24 15:30:01-05:00 R6,IS 11.6100 100
2015-02-24 15:30:01-05:00 11.6100 375
2015-02-24 15:30:01-05:00 R6,IS 11.6100 100
... ... ... ...
2015-02-24 15:59:55-05:00 R6,IS 11.5850 100
2015-02-24 15:59:55-05:00 R6,IS 11.5800 200
2015-02-24 15:59:55-05:00 T 11.5850 100
2015-02-24 15:59:56-05:00 R6,IS 11.5800 175
2015-02-24 15:59:56-05:00 R6,IS 11.5800 225
[5187 rows x 3 columns]
我有一个名为 codes
的 numpy
数组:
array(['4', 'AP', 'CM', 'BP', 'FA', 'FI', 'NC', 'ND', 'NI', 'NO', 'PT',
'PV', 'PX', 'SD', 'WO'],
dtype='|S2')
我需要过滤 trades
,如果 codes
中的任何值包含在 trades['Codes']
中,则该行被排除。目前我正在这样做:
ix = trades.Codes.str.split(',').apply(lambda cs: not any(c in excludes for c in cs))
trades = trades[ix]
但是,这太慢了,我需要让它更快。我想使用 cython(如 here or maybe numba 所述,看来 cython 是更好的选择。
我基本上需要这样的功能:
def isinCodes(codes_array1, codes_array2):
for x in codes_array1:
for y in codes_array2:
if x == y: return True
return False
cythonizing 时需要使用哪些类型?
这很容易向量化。
构造一个框架,我拿了100000*你的例子,1M行。
In [76]: df2.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 1000000 entries, 0 to 9
Data columns (total 4 columns):
date 1000000 non-null datetime64[ns]
code 900000 non-null object
price 1000000 non-null float64
volume 1000000 non-null int64
dtypes: datetime64[ns](1), float64(1), int64(1), object(1)
memory usage: 38.1+ MB
In [77]: df2.head()
Out[77]:
date code price volume
0 2015-02-24 20:30:01 R6,IS 11.61 100
1 2015-02-24 20:30:01 R6,IS 11.61 100
2 2015-02-24 20:30:01 R6,IS 11.61 100
3 2015-02-24 20:30:01 NaN 11.61 375
4 2015-02-24 20:30:01 R6,IS 11.61 100
此代码实际上是:df2.code.str.split(',',expand=True)
,但 ATM 存在性能问题,将在 0.16.2 中修复,请参阅 here。所以这段代码以非常高效的方式进行拆分。
In [78]: result = DataFrame([ [ s ] if not isinstance(s, list) else s for s in df2.code.str.split(',') ],columns=['A','B'])
In [79]: %timeit DataFrame([ [ s ] if not isinstance(s, list) else s for s in df2.code.str.split(',') ],columns=['A','B'])
1 loops, best of 3: 941 ms per loop
In [80]: result.head()
Out[80]:
A B
0 R6 IS
1 R6 IS
2 R6 IS
3 NaN None
4 R6 IS
我在isin
的最后加了'T'In [81]: isin
Out[81]:
['4',
'AP',
'CM',
'BP',
'FA',
'FI',
'NC',
'ND',
'NI',
'NO',
'PT',
'PV',
'PX',
'SD',
'WO',
'T']
结果
In [82]: df2[(result.A.isin(isin) | result.A.isin(isin))].info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 100000 entries, 7 to 7
Data columns (total 4 columns):
date 100000 non-null datetime64[ns]
code 100000 non-null object
price 100000 non-null float64
volume 100000 non-null int64
dtypes: datetime64[ns](1), float64(1), int64(1), object(1)
memory usage: 3.8+ MB
In [83]: df2[(result.A.isin(isin) | result.A.isin(isin))].head()
Out[83]:
date code price volume
7 2015-02-24 20:59:55 T 11.585 100
7 2015-02-24 20:59:55 T 11.585 100
7 2015-02-24 20:59:55 T 11.585 100
7 2015-02-24 20:59:55 T 11.585 100
7 2015-02-24 20:59:55 T 11.585 100
实际操作比拆分到这里要快很多
In [84]: %timeit df2[(result.A.isin(isin) | result.A.isin(isin))]
10 loops, best of 3: 106 ms per loop