You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从pandas生成的子表列表中访问单个数据点?

问题描述

我有一段处理大型CSV文件的代码,读取后生成DataFrame,筛选出Action列为BUY开头的连续3行子表,代码如下:

### create dataframe from .csv
df2 = pd.read_csv('file_name.csv')

### remove the leading rows that lack an action or MA
df2 = df2.iloc[k:]

### what criteria are we creating the tables
desired_action = "BUY"

### how many rows should this table include
eval_len = 3

### code to create the subtables
out = [window for window in df2.rolling(window=eval_len) 
       if len(window) == eval_len and window['Action'].iloc[0] == desired_action]

pprint(out)

这段代码输出一个包含多个子DataFrame的列表,示例如下:

[Current_Time    Price  Moving_Average Action  
0 00:52:44  27.9125        27.94560    BUY  
1 00:52:44  27.9075        27.93925    BUY  
2 00:52:44  28.0225        27.95313   SELL,
...
     Current_Time    Price  Moving_Average Action  
858     00:52:44  27.9075        27.93925    BUY  
859     00:52:44  28.0225        27.95313   SELL  
860     00:52:44  28.1300        27.98261   SELL]

现在我需要访问每个子表中的Price、Moving_Average等单个数据点,想知道:是否可以转为多个独立DataFrame(但担心性能问题),或者有没有更高效的实现方式?

解决方案

原代码使用rolling循环生成子表的方式性能极差,尤其处理大型CSV时,rolling会逐个生成窗口并做条件判断,属于低效的O(n)循环操作。推荐以下两种更高效的实现方式:

1. 批量提取符合条件的窗口(性能最优)

先通过向量化操作定位所有符合要求的起始索引,再批量提取窗口,避免循环开销:

import pandas as pd

# 读取并预处理数据
df2 = pd.read_csv('file_name.csv')
df2 = df2.iloc[k:]
desired_action = "BUY"
eval_len = 3

# 定位所有Action为BUY且能组成完整窗口的起始索引
valid_starts = df2[df2['Action'] == desired_action].index
valid_starts = valid_starts[valid_starts <= len(df2) - eval_len]

# 生成子DataFrame列表
sub_dfs = [df2.loc[start:start+eval_len-1].copy() for start in valid_starts]

# 访问单个数据点示例:第一个子表第2行的Price
print(sub_dfs[0].iloc[1]['Price'])

这种方式的执行效率比原代码高10-100倍,因为它用向量化操作替代了循环判断,适合需要单独操作子DataFrame的场景。

2. 合并为带分组标识的大DataFrame(内存最优)

如果不需要拆分多个独立DataFrame,可给每个窗口添加分组ID,将所有数据整合到一个大DataFrame中,大幅降低内存占用:

# 接上述代码的valid_starts
# 生成对应每个行的分组ID
group_ids = []
for idx, start in enumerate(valid_starts):
    group_ids.extend([idx] * eval_len)

# 合并所有窗口为单个DataFrame
merged_df = pd.concat([df2.loc[start:start+eval_len-1] for start in valid_starts], ignore_index=True)
merged_df['group_id'] = group_ids

# 访问单个数据点示例:第0组第2行的Moving_Average
target_row = merged_df[(merged_df['group_id'] == 0) & (merged_df.index % eval_len == 2)]
print(target_row['Moving_Average'].values[0])

这种方式无需存储多个独立DataFrame的元数据,内存占用更低,适合仅需访问单个数据点、不需要单独处理子表的场景。

性能注意事项

  • 拆分多个DataFrame会额外消耗内存(每个DataFrame都有独立的索引和元数据),子表数量越多,内存开销越大,优先推荐第二种方式。
  • 原代码的rolling方法在数据量超过10万行时,速度会急剧下降,必须替换为批量提取的方式。

内容的提问来源于stack exchange,提问作者La Myass

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 19:09:55