Pandas Apply and Loc - 效率和索引
Pandas Apply and Loc - efficiency and indexing
我想在满足特定条件的每一行之后找到第一个值。因此,例如,我想在当前行增加 5% 之后找到第一个 rate/value(不一定是第一个 行 之后)。添加的列将是最后一个 'first5percentIncrease' 并且将是第一行(在当前行之后)的索引(and/or 值),增加了 5%。注意每个都不能低于当前行的索引。
amount date rate total type first5percentIncreaseValue first5percentIncreaseIndex
9248 0.05745868 2018-01-22 06:11:36 10 0.00099984 buy 10.5 9341
9249 1.14869147 2018-01-22 06:08:38 20 0.01998989 buy 21 9421
9250 0.16498080 2018-01-22 06:02:59 15 0.00286241 sell 15.75 9266
9251 0.02881844 2018-01-22 06:01:54 2 0.00049999 sell 2.1 10911
我尝试使用 loc 将它应用于每一行。仅约 9k 行的输出至少需要 10 秒。这完成了工作(我得到了比给定行高 5% 的所有值的列表)但是有没有更有效的方法来做到这一点?我也只想获得第一个值,但是当我这样做时,我认为它是从第一行开始的。有没有办法从当前行开始 .locs 搜索,这样我就可以只取第一个值?
coin_trade_history_df['rate'].apply(
lambda y: coin_trade_history_df['rate'].loc[coin_trade_history_df['rate'].apply(
lambda x: y >= x + (x*.005))])
0 [0.01387146, 0.01387146, 0.01387148, 0.0138714...
1 [0.01387146, 0.01387146, 0.01387148, 0.0138714...
2 [0.01387146, 0.01387146, 0.01387148, 0.0138714...
3 [0.01387146, 0.01387146, 0.01387148, 0.0138714...
4 [0.01387146, 0.01387146, 0.01387148, 0.0138714...
Name: rate, dtype: object
进一步说明Peter Leimbigler说得比我好:
哦,我想我现在明白了! "For each row, scan downward and get the first row you encounter that shows an increase of at least 5%," 对吧?我会编辑我的答案 :) – Peter Leimbigler
下面是使用下一个可用行的索引标记每一行的具体示例的方法,该行显示至少增加了 5%。
# Example data
df = pd.DataFrame({'rate': [100, 105, 99, 110, 130, 120, 98]})
# Series.shift(n) moves elements n places forward = down. We use
# it here in the denominator in order to compare each change with
# the initial value, rather than the final value.
mask = df.rate.diff()/df.rate.shift() >= 0.05
df.loc[mask, 'next_big_change_idx'] = df[mask].index
df.next_big_change_idx = df.next_big_change_idx.bfill().shift(-1)
# output
df
rate next_big_change_idx
0 100 1.0
1 105 3.0
2 99 3.0
3 110 4.0
4 130 NaN
5 120 NaN
6 98 NaN
Peter 的回答要快得多,但它只查看了紧邻的下一行。我希望它在每一行都执行此操作。下面是我最终得到的结果——不是很快,但它遍历每一行和 returns 满足我的标准(增加 5%)的第一个值(或我的情况下的最后一个值,因为我的时间序列正在下降)。
def test_rows(x):
return trade_history_df['rate'].loc[
trade_history_df['rate'] >= x['rate'] + (x['rate'] * .05)].loc[
trade_history_df['date'] > x['date']].last_valid_index()
test1 = trade_history_df[['rate','date']].apply(test_rows,axis = 1)
我想在满足特定条件的每一行之后找到第一个值。因此,例如,我想在当前行增加 5% 之后找到第一个 rate/value(不一定是第一个 行 之后)。添加的列将是最后一个 'first5percentIncrease' 并且将是第一行(在当前行之后)的索引(and/or 值),增加了 5%。注意每个都不能低于当前行的索引。
amount date rate total type first5percentIncreaseValue first5percentIncreaseIndex
9248 0.05745868 2018-01-22 06:11:36 10 0.00099984 buy 10.5 9341
9249 1.14869147 2018-01-22 06:08:38 20 0.01998989 buy 21 9421
9250 0.16498080 2018-01-22 06:02:59 15 0.00286241 sell 15.75 9266
9251 0.02881844 2018-01-22 06:01:54 2 0.00049999 sell 2.1 10911
我尝试使用 loc 将它应用于每一行。仅约 9k 行的输出至少需要 10 秒。这完成了工作(我得到了比给定行高 5% 的所有值的列表)但是有没有更有效的方法来做到这一点?我也只想获得第一个值,但是当我这样做时,我认为它是从第一行开始的。有没有办法从当前行开始 .locs 搜索,这样我就可以只取第一个值?
coin_trade_history_df['rate'].apply(
lambda y: coin_trade_history_df['rate'].loc[coin_trade_history_df['rate'].apply(
lambda x: y >= x + (x*.005))])
0 [0.01387146, 0.01387146, 0.01387148, 0.0138714...
1 [0.01387146, 0.01387146, 0.01387148, 0.0138714...
2 [0.01387146, 0.01387146, 0.01387148, 0.0138714...
3 [0.01387146, 0.01387146, 0.01387148, 0.0138714...
4 [0.01387146, 0.01387146, 0.01387148, 0.0138714...
Name: rate, dtype: object
进一步说明Peter Leimbigler说得比我好:
哦,我想我现在明白了! "For each row, scan downward and get the first row you encounter that shows an increase of at least 5%," 对吧?我会编辑我的答案 :) – Peter Leimbigler
下面是使用下一个可用行的索引标记每一行的具体示例的方法,该行显示至少增加了 5%。
# Example data
df = pd.DataFrame({'rate': [100, 105, 99, 110, 130, 120, 98]})
# Series.shift(n) moves elements n places forward = down. We use
# it here in the denominator in order to compare each change with
# the initial value, rather than the final value.
mask = df.rate.diff()/df.rate.shift() >= 0.05
df.loc[mask, 'next_big_change_idx'] = df[mask].index
df.next_big_change_idx = df.next_big_change_idx.bfill().shift(-1)
# output
df
rate next_big_change_idx
0 100 1.0
1 105 3.0
2 99 3.0
3 110 4.0
4 130 NaN
5 120 NaN
6 98 NaN
Peter 的回答要快得多,但它只查看了紧邻的下一行。我希望它在每一行都执行此操作。下面是我最终得到的结果——不是很快,但它遍历每一行和 returns 满足我的标准(增加 5%)的第一个值(或我的情况下的最后一个值,因为我的时间序列正在下降)。
def test_rows(x):
return trade_history_df['rate'].loc[
trade_history_df['rate'] >= x['rate'] + (x['rate'] * .05)].loc[
trade_history_df['date'] > x['date']].last_valid_index()
test1 = trade_history_df[['rate','date']].apply(test_rows,axis = 1)