【问题标题】:Faster way to select rows in Pandas and put them into a list?在 Pandas 中选择行并将它们放入列表中的更快方法?
【发布时间】:2021-05-16 12:11:12
【问题描述】:

我有一个包含 600 万行的数据框,目前我正在执行以下操作:

symbol = 'BPCL'
rows=[]
start = time.time()
times = fut_df.timestamp.tolist()
for t in times:
    s_df = fut_df[fut_df['timestamp'] == t]
    s_df.sort_values('expiry', inplace=True)
    if len(s_df) > 0:
        # s_df.reset_index(drop=True, inplace=True)
        # count += 1
        while len(s_df) < 3:
            s_df.loc[len(s_df)] = [0, 0, 0, 0, 0, 0, 0, 0, 0]
        rows.append([symbol, t,
                     s_df['close_under'].iloc[0], 
                     s_df['contractname'].iloc[0], s_df['close'].iloc[0],
                     s_df['contractname'].iloc[1], s_df['close'].iloc[1], 
                     s_df['contractname'].iloc[2], s_df['close'].iloc[2])
print(time.time() - start)

这对我来说似乎不是很有效。并且需要很多时间。有没有更多的 pandas/pythonic 方式来做到这一点?我认为lambda 可能工作得更快或map

fut_df 的示例:

        contractname           timestamp   close     bid     ask  close_under  bid_under  ask_under     expiry
7485094  BPCL20MAYFUT 2020-04-30 15:29:52  372.20  371.85  372.75       371.85     371.85      371.9 2020-05-01
7485095  BPCL20APRFUT 2020-04-30 15:29:52  371.50  371.45  373.65       371.85     371.85      371.9 2020-04-01
7485096  BPCL20APRFUT 2020-04-30 15:29:52  371.50  371.05  373.65       371.85     371.85      371.9 2020-04-01
7485097  BPCL20MAYFUT 2020-04-30 15:29:53  372.20  371.85  372.75       371.85     371.85      371.9 2020-05-01
7485098  BPCL20APRFUT 2020-04-30 15:29:53  371.50  371.05  373.65       371.85     371.85      371.9 2020-04-01
7485099  BPCL20MAYFUT 2020-04-30 15:29:54  372.20  372.00  372.70       371.00     371.00      371.9 2020-05-01
7485100  BPCL20APRFUT 2020-04-30 15:29:54  371.50  371.05  373.65       371.00     371.00      371.9 2020-04-01
7485101  BPCL20MAYFUT 2020-04-30 15:29:55  372.20  372.00  372.70       371.85     371.85      371.9 2020-05-01
7485102  BPCL20APRFUT 2020-04-30 15:29:55  371.50  371.35  373.65       371.85     371.85      371.9 2020-04-01
7485103  BPCL20JUNFUT 2020-04-30 15:29:56  372.45  372.15  373.95       371.90     371.85      371.9 2020-06-01
7485104  BPCL20APRFUT 2020-04-30 15:29:56  371.50  371.05  373.65       371.90     371.85      371.9 2020-04-01
7485105  BPCL20MAYFUT 2020-04-30 15:29:56  372.70  372.00  372.75       371.90     371.85      371.9 2020-05-01
7485106  BPCL20APRFUT 2020-04-30 15:29:57  371.50  371.10  373.65       371.85     371.85      371.9 2020-04-01
7485107  BPCL20MAYFUT 2020-04-30 15:29:57  372.70  372.00  372.75       371.85     371.85      371.9 2020-05-01
7485108  BPCL20APRFUT 2020-04-30 15:29:58  371.50  371.40  373.65       371.90     371.85      371.9 2020-04-01
7485109  BPCL20MAYFUT 2020-04-30 15:29:59  372.70  372.00  372.75       371.85     371.85      371.9 2020-05-01

创建行后的预期输出我会将它们放入数据框中:

symbol timestamp close_under m1 m1_close m2 m2_close m3 m3_close

BPCL 2020-04-30 15:29:52 371.85 BPCL20APRFUT 371.50  BPCL20MAYFUT 372.20 0 0

当前代码大约需要 28 小时才能通过数据框。我怎样才能加快速度?我正在使用multiprocessing/concurrent.futures 一次浏览多个文件。

【问题讨论】:

  • AttributeError: 'DataFrame' 对象没有属性 'times'
  • 如果您可以将问题浓缩为单个功能,例如“收盘价”并提供特征较少但要测试的数据点较多的样本。作为一般提示,您可以尝试完全避免循环。
  • @Andreas 改变了它。它应该是timestamp
  • 谢谢,但似乎 symbol 也没有定义。请注意,如果您尝试使用本机方法,pandas 可以提供更高的性能。在你的情况下,我会尝试使用 groupby。如果您可以提供一个包含多个输入行但只有 2 个结果行的示例,我可以向您展示一个小示例。
  • @Andreas 是的,最好避免循环,但我仍在努力思考如何对操作进行矢量化。我正在添加更多数据点并减少功能。

标签: python pandas


【解决方案1】:

你可以试试这样的:

d = {'close_under':'first','close':'last','bid':'first'}
df = fut_df.groupby(['contractname', 'timestamp']).aggregate(d)

出来:

                        close_under  close     bid
contractname timestamp                            
2020-04-30   15:29:52        371.85  371.5  371.85
             15:29:53        371.85  371.5  371.85
             15:29:54        371.00  371.5  372.00
             15:29:55        371.85  371.5  372.00
             15:29:56        371.90  372.7  372.15
             15:29:57        371.85  372.7  371.10
             15:29:58        371.90  371.5  371.40
             15:29:59        371.85  372.7  372.00

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-06
    • 1970-01-01
    • 2021-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多