将计算列添加到Panel内的每个DataFrame,而不进行for循环

时间:2013-09-22 17:06:31

标签: python pandas

我有~300个.csv文件,所有文件都有相同数量的行和列用于检测数据。由于每个.csv文件代表一天并且结构相同,我认为最好将每个.csv拉入Pandas DataFrame,然后将它们抛入Panel对象以执行更快的计算。

我想为Panel内的每个DataFrame添加额外的计算列,最好不要使用for循环。我尝试将“应用”功能用于面板,并根据附加了“' p”的原始列名称命名新列。 (以便以后更容易索引)。以下是我目前使用的代码。

import pandas as pd
import numpy as np
import os.path

dir = "data/testsetup1/"
filelist = []

def initializeDataFrames():
    for f in os.listdir(dir):
        if ".csv" in f:
                filelist.append(dir + f)

    dd={}
    for f in filelist:
        dd[f[len(dir):(len(f)-4)]] = pd.read_csv(f)

    return pd.Panel(dd)

def newCalculation(pointSeries):
#test function, more complex functions to follow

    pointSeriesManiuplated = pointSeries.copy()

    percentageMove = 1.0/float(len(pointSeriesManiuplated)) 

    return pointSeriesManiuplated * percentageMove


myPanel = initializeDataFrames()
#calculatedPanel = myPanel.join(lambda x: myPanel[x,:,0:17].apply(lambda y:newCalculation(myPanel[x,:,0:17].ix[y])), rsuffix='p')
calculatedPanel = myPanel.ix[:,:,0:17].join(myPanel.ix[:,:,0:17].apply(lambda x: newCalculation(x), axis=2), rsuffix='p')

print calculatedPanel.values

上面的代码目前使用计算列复制每个DataFrame,而不是将它们附加到每个DataFrame。我使用的apply函数对Series对象进行操作,在这种情况下,它将是一个传递列。 我的问题是如何在Panel上使用apply函数,以便计算新列并将它们附加到每个DataFrame?

提前致谢。

2 个答案:

答案 0 :(得分:0)

如果您想通过apply添加新列,只需将apply操作的输出分配给您想要的列:

myPanel['new_column_suffix_p'] = myPanel.apply(newCalculation)

如果您想要多个列,可以为此创建自定义函数:

def calc_new_columns (rowset):
    rowset['newcolumn1'] = calculation1(rowset.columnofinterest)
    rowset['newcolumn2'] = calculation2(rowset.columnofinterest2 + rowset.column3)
    return rowset
myPanel = myPanel.apply(calc_new_columns)

更广泛的说明。您可以手动处理数据框的各个部分,看起来您可以一次完成新的列操作。我建议将第一个csv文件导入数据框。然后遍历剩余的299 csv并使用DataFrame.append添加到原始数据框。然后,对于简单需要计算列添加的所有数据,您将拥有一个数据框。

答案 1 :(得分:0)

nit:“dir”是内置函数。你不应该将它用作变量名。

尝试使用双转置:

p = pd.Panel(np.random.rand(4,10,17),
             items=pd.date_range('2013/11/10',periods=4),
             major_axis=range(10),
             minor_axis=map(lambda x: "col%d" % x, range(17)))

pT = p.transpose(2,1,0)
pT = pT.join(pT.apply(newCalculation, axis='major'), rsuffix='p')
p = pT.transpose(2,1,0)