【发布时间】:2017-04-06 10:01:29
【问题描述】:
我正在寻找执行以下操作的最快方法:
我们有一个 pd.DataFrame:
df = pd.DataFrame({
'High': [1.3,1.2,1.1],
'Low': [1.3,1.2,1.1],
'High1': [1.1, 1.1, 1.1],
'High2': [1.2, 1.2, 1.2],
'High3': [1.3, 1.3, 1.3],
'Low1': [1.3, 1.3, 1.3],
'Low2': [1.2, 1.2, 1.2],
'Low3': [1.1, 1.1, 1.1]})
看起来像:
In [4]: df
Out[4]:
High High1 High2 High3 Low Low1 Low2 Low3
0 1.3 1.1 1.2 1.3 1.3 1.3 1.2 1.1
1 1.2 1.1 1.2 1.3 1.2 1.3 1.2 1.1
2 1.1 1.1 1.2 1.3 1.1 1.3 1.2 1.1
我想知道的是,High1、High2、High3 浮点值中的哪一个是第一个大于或等于 High 值的。如果没有,应该是np.nan
对于 Low1、Low2、Low3 值也是如此,但在这种情况下,它们中的哪一个是第一个低于或等于 High 值的值。如果没有,应该是np.nan
最后,我需要知道先出现的是低位还是高位。
解决此问题的一种方法是:
df['LowIs'] = np.nan
df['HighIs'] = np.nan
for i in range(1,4):
df['LowIs'] = np.where((np.isnan(df['LowIs'])) & (
df['Low'] >= df['Low'+str(i)]), i, df['LowIs'])
df['HighIs'] = np.where((np.isnan(df['HighIs'])) & (
df['High'] <= df['High'+str(i)]), i, df['HighIs'])
df['IsFirst'] = np.where(
df.LowIs < df.HighIs,
'Low',
np.where(df.LowIs > df.HighIs, 'High', 'None')
)
这给了我:
In [8]: df
Out[8]:
High High1 High2 High3 Low Low1 Low2 Low3 LowIs HighIs IsFirst
0 1.3 1.1 1.2 1.3 1.3 1.3 1.2 1.1 1.0 3.0 Low
1 1.2 1.1 1.2 1.3 1.2 1.3 1.2 1.1 2.0 2.0 None
2 1.1 1.1 1.2 1.3 1.1 1.3 1.2 1.1 3.0 1.0 High
由于我必须在高/低将不同的许多迭代中一遍又一遍地执行此操作,因此执行此操作时的性能是关键。
所以我不介意 High1、High2、High3 和 Low1、Low2、Low3 是否在一个单独的转置的 DataFrame 中,或者它是否在一个 dict 中。因此,以任何能提供最佳性能的方式准备数据的过程可能会很慢而且很尴尬。
我研究过的一个解决方案是:
df.loc[(df.index == 0), 'HighIs'] = np.where(
df.loc[(df.index == 0), ['High1', 'High2', 'High3']] >= 1.3
)[1][0] + 1
所以检查第一行中哪一列是真的,然后查看 np.where() 的索引号。
期待任何建议,希望能学到新东西! :)
【问题讨论】:
-
这是您最终希望解决的问题,还是您在解决其他问题时遇到的问题?只是问,因为这似乎是一个可能的x-y problem。
标签: python performance pandas numpy vectorization