【问题标题】:efficiently growing a large dataframe vertically有效地垂直增长大型数据框
【发布时间】:2019-04-21 22:44:19
【问题描述】:

我有以下代码递归遍历包含数千个 csv 的目录,并尝试将它们全部读取并添加到一个 DataFrame:

df = pd.DataFrame()
symbol = symbol.upper()

for filepath in glob.iglob(r'W:\data\{0}\option\**\**\**.csv'.format(188), recursive=True):

    optionNameCSI = filepath.split("\\")[-1].split('.')[0]
    try:
        tmp = pd.read_csv(filepath, engine='c')
        strike = tmp['Strike'].iloc[-1]
        expiry = pd.to_datetime(tmp['Option Expiration Date'].iloc[-1])
        m = expiry.month
        y = expiry.year
        PutCall = tmp['PutCall'].iloc[-1]
        future = symbol + numToLetter[m] + str(y)
    except (IndexError, KeyError) as e:
        continue

    if tmp.empty:
        df = tmp
    else:
        df = df.append(tmp)

    print(optionName, 'loaded')

但是,此代码开始迭代非常快,然后以指数方式减慢并且永远不会完成。有什么我做错了吗?我知道文件路径都是正确获取的,所以问题在于 DataFrame 的增长。

【问题讨论】:

  • 您在循环中附加到 DataFrame,这会不必要地复制数据并且效率极低(这就是为什么开始时很好,但随后会停止的原因)。追加到循环内的列表并在之后连接一次。
  • Alexander's Solution 说明了这一点。
  • 不错!我没有意识到这一点。如果我们尽可能地提高效率,Alexander 的解决方案的性能与串联相比有什么显着差异吗?
  • 我只使用csv 模块tbh。我在增长这样的 DF 方面所做的每一次尝试都在降低速度和内存。我还没有找到解决它的方法。也许是奇怪的连接或连接,但是一旦你把它放在一个循环中,开销就会很大。

标签: python pandas


【解决方案1】:

考虑将您的代码分成单独的函数,如下所示:

def get_data_from_csv(filepath):
    optionNameCSI = filepath.split("\\")[-1].split('.')[0]
    try:
        df = pd.read_csv(filepath, engine='c')
        # do stuff ...
        return df
    except (IndexError, KeyError) as e:
        return

然后您可以使用列表推导来收集上面人们建议的列表中的所有数据

filepaths = glob.iglob(r'W:\data\{0}\option\**\**\**.csv'.format(188), recursive=True)
result = [get_data_from_csv(filepath) for filepath in filepaths]
result = [r for r in result if r is not None] # remove 'None' values

然后使用pd.concat加入数据

df = pd.concat(result)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-18
    • 2019-07-09
    • 2013-03-13
    • 1970-01-01
    相关资源
    最近更新 更多