Създаване на празна Pandas DataFrame и след това запълването ѝ?

Започвам от документацията на pandas DataFrame тук: http://pandas.pydata.org/pandas-docs/stable/dsintro.html

Бих искал итеративно да запълня DataFrame със стойности при изчисление от типа на времеви серии. Така че основно бих искал да инициализирам DataFrame с колони A, B и редове с времеви маркери, всички 0 или всички NaN.

След това бих добавил начални стойности и бих преминал през тези данни, изчислявайки новия ред от предишния ред, да речем row[A][t] = row[A][t-1]+1 или така.

В момента използвам кода по-долу, но ми се струва, че той е доста грозен и трябва да има начин да се направи това директно с DataFrame или просто по-добър начин като цяло. Забележка: Използвам Python 2.7.

import datetime as dt
import pandas as pd
import scipy as s

if __name__ == '__main__':
    base = dt.datetime.today().date()
    dates = [ base - dt.timedelta(days=x) for x in range(0,10) ]
    dates.sort()

    valdict = {}
    symbols = ['A','B', 'C']
    for symb in symbols:
        valdict[symb] = pd.Series( s.zeros( len(dates)), dates )

    for thedate in dates:
        if thedate > dates[0]:
            for symb in valdict:
                valdict[symb][thedate] = 1+valdict[symb][thedate - dt.timedelta(days=1)]

    print valdict
Решение

Ето няколко предложения:

Използвайте date_range за индекса:

import datetime
import pandas as pd
import numpy as np

todays_date = datetime.datetime.now().date()
index = pd.date_range(todays_date-datetime.timedelta(10), periods=10, freq='D')

columns = ['A','B', 'C']

Забележка: бихме могли да създадем празна DataFrame (с NaNs), като просто напишем:

df_ = pd.DataFrame(index=index, columns=columns)
df_ = df_.fillna(0) # with 0s rather than NaNs

За да направите този тип изчисления за данните, използвайте масив numpy:

data = np.array([np.arange(10)]*3).T

Следователно можем да създадем DataFrame:

In [10]: df = pd.DataFrame(data, index=index, columns=columns)

In [11]: df
Out[11]: 
            A  B  C
2012-11-29  0  0  0
2012-11-30  1  1  1
2012-12-01  2  2  2
2012-12-02  3  3  3
2012-12-03  4  4  4
2012-12-04  5  5  5
2012-12-05  6  6  6
2012-12-06  7  7  7
2012-12-07  8  8  8
2012-12-08  9  9  9
Коментари (7)

I Ако искате просто да създадете празна рамка от данни и да я запълните с някои входящи рамки от данни по-късно, опитайте това:

В този пример използвам this pandas doc, за да създам нова рамка от данни, и след това използвам append, за да запиша в новата рамка от данни с данни от старата рамка от данни.


Погледнете това

newDF = pd.DataFrame() #creates a new dataframe that's empty
newDF = newDF.append(oldDF, ignore_index = True) # ignoring index is optional
# try printing some data from newDF
print newDF.head() #again optional 
  • ако трябва да продължа да добавям нови данни в този newDF от повече от един oldDF, просто използвам цикъл for, за да итерирам над pandas.DataFrame.append()
Коментари (3)

I Ако искате да въведете имената на колоните от самото начало, използвайте този подход:

import pandas as pd

col_names =  ['A', 'B', 'C']
my_df  = pd.DataFrame(columns = col_names)
my_df

Ако искате да добавите запис към рамката с данни, по-добре е да използвате следния начин:

my_df.loc[len(my_df)] = [2, 4, 5]

Също така може да искате да подадете речник:

my_dic = {'A':2, 'B':4, 'C':5}
my_df.loc[len(my_df)] = my_dic 

Ако искате да добавите друга рамка от данни към my_df, направете следното:

col_names =  ['A', 'B', 'C']
my_df2  = pd.DataFrame(columns = col_names)
my_df = my_df.append(my_df2)

I Ако добавяте редове в цикъл, помислете за проблеми с производителността:
За първите около 1000 записа "my_df.loc" производителността е по-добра, но постепенно става по-бавна с увеличаване на броя на записите в цикъла.

Ако възнамерявате да правите тънки операции в голям цикъл (например 10 млн. записа или повече):
По-добре е да използвате комбинация от тези две опции; запълване на рамка от данни с iloc, докато размерът ѝ стане около 1000, след което я добавете към оригиналната рамка от данни и изпразнете временната рамка от данни. Това ще повиши производителността ви около 10 пъти.

Коментари (0)