有什么更有效的方法遍历熊猫数据框?

时间:2019-03-04 19:04:13

标签: python

我需要从37,000个xls文件中提取一些数据,这些文件存储在2100个文件夹中(活动/年/月/日)。我已经写了脚本,但是如果给出一千个文件的小样本,则需要5分钟才能运行。每个文件最多可以包含一万个我需要提取的条目。尚未尝试在整个文件夹上运行它,我正在寻找有关提高效率的建议。

我还希望获得有关如何将字典导出到新的Excel文件,两列或如何跳过整个字典并将其直接保存到xls以及如何将整个脚本指向共享驱动器文件夹的帮助,而不是Python的根。

import fnmatch
import os
import pandas as pd

docid = []
CoCo = []

for root, dirs, files in os.walk('Z_Option'):
    for filename in files:
        if fnmatch.fnmatch(filename, 'Z_*.xls'):
            df = pd.read_excel(os.path.join(root, filename), sheet_name='Sheet0')

            for i in df['BLDAT']:
                if isinstance(i, int):
                    docid.append(i)
                    CoCo.append(df['BUKRS'].iloc[1])

data = dict(zip(docid, CoCo))
print(data)

2 个答案:

答案 0 :(得分:0)

This walkthrough在我接触大熊猫时对我非常有帮助。 for i in df['BLDAT']行可能需要很长时间。

使用诸如apply函数之类的东西可以提高速度:

def check_if_int(row): #row is effectively a pd.Series of the index
    if type(row['BLDAT']) == 'int':
        docid.append(i)
        CoCo.append(row.name) #name should be the index

df.apply(check_if_int, axis = 1) #axis = 1 will work rowwise

目前尚不清楚此脚本到底要做什么,但是如果像过滤数据框那样简单,只包含'BLDAT'列是整数的行,那么使用掩码会更快

df_filtered = df.loc[type(df['BLDAT']) == 'int'] #could also use .isinstance()

与创建列表相比,筛选数据框的另一个优点是可以使用熊猫函数df_filtered.to_csv()将文件输出为.xlsx兼容文件。

答案 1 :(得分:0)

最终,由于时间限制,我放弃了(是最后一分钟的“明天我需要这个”报告),并提出了这个建议。删除空白行会有所帮助,在下一季度中,我将尝试完全使用熊猫来完成此操作。

#Shared drive
import fnmatch
import os
import pandas as pd
import time

start_time = time.time()
docid = []
CoCo = []
os.chdir("X:\Shared activities")
for root, dirs, files in os.walk("folder"):
    for filename in files:
        if fnmatch.fnmatch(filename, 'Z_*.xls'):
            try:
                df = pd.read_excel(os.path.join(root, filename), sheet_name='Sheet0')
                df.dropna(subset = ['BLDAT'], inplace = True)
                for i in df['BLDAT']:
                    if isinstance(i, int):
                        docid.append(i)
                        CoCo.append(df['BUKRS'].iloc[1])
            except:
                errors.append((os.path.join(root, filename)))

data = dict(zip(docid, CoCo))
os.chdir("C:\project\reports")
pd.DataFrame.from_dict(data, orient="index").to_csv('test.csv')
with open('errors.csv', 'w') as f:
    for item in errors:
        f.write("%s\n" % item)
print("--- %s seconds ---" % (time.time() - start_time))