Mat*_*uer 381 python dataframe pandas
我从这里的pandas DataFrame文档开始:http://pandas.pydata.org/pandas-docs/stable/dsintro.html
我想迭代地使用时间序列计算中的值填充DataFrame.基本上,我想用列A,B和时间戳行初始化DataFrame,全部为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
Run Code Online (Sandbox Code Playgroud)
And*_*den 281
以下是一些建议:
使用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']
Run Code Online (Sandbox Code Playgroud)
注意:我们可以NaN
简单地通过编写来创建一个空的DataFrame(带有s):
df_ = pd.DataFrame(index=index, columns=columns)
df_ = df_.fillna(0) # with 0s rather than NaNs
Run Code Online (Sandbox Code Playgroud)
要对数据执行这些类型的计算,请使用numpy数组:
data = np.array([np.arange(10)]*3).T
Run Code Online (Sandbox Code Playgroud)
因此我们可以创建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
Run Code Online (Sandbox Code Playgroud)
gee*_*rsh 136
如果您只是想创建一个空数据框并稍后用一些传入数据框填充它,请尝试以下方法:
在这个例子中,我使用这个pandas doc创建一个新的数据框,然后使用append用newDF中的数据写入newDF.
看看这个
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
Run Code Online (Sandbox Code Playgroud)
Afs*_*iri 106
如果您想从一开始就拥有列名,请使用以下方法:
import pandas as pd
col_names = ['A', 'B', 'C']
my_df = pd.DataFrame(columns = col_names)
my_df
Run Code Online (Sandbox Code Playgroud)
如果要向数据帧添加记录,最好使用:
my_df.loc[len(my_df)] = [2, 4, 5]
Run Code Online (Sandbox Code Playgroud)
您可能还想传递字典:
my_dic = {'A':2, 'B':4, 'C':5}
my_df.loc[len(my_df)] = my_dic
Run Code Online (Sandbox Code Playgroud)
但是,如果要将另一个数据帧添加到my_df,请执行以下操作:
col_names = ['A', 'B', 'C']
my_df2 = pd.DataFrame(columns = col_names)
my_df = my_df.append(my_df2)
Run Code Online (Sandbox Code Playgroud)
如果要在循环内添加行,请考虑性能问题;
对于大约前1000条记录,"my_df.loc"性能更好,并且通过增加循环中的记录数逐渐变慢.
如果你计划在一个大循环内(比如10M记录左右)
那么你最好使用这两者的混合物; 使用iloc填充数据帧,直到大小达到1000,然后将其附加到原始数据帧,并清空临时数据帧.这会使你的表现提高大约10倍
cs9*_*s95 68
TLDR;(只需阅读粗体文字)
这里的大多数答案将告诉您如何创建一个空的DataFrame并填写它,但是没有人会告诉您这是一件坏事。
这是我的建议:等待直到您确定拥有所有需要使用的数据。使用列表收集数据,然后在准备好时初始化DataFrame。
data = []
for a, b, c in some_function_that_yields_data():
data.append([a, b, c])
df = pd.DataFrame(data, columns=['A', 'B', 'C'])
Run Code Online (Sandbox Code Playgroud)
一次添加到列表并创建一个DataFrame总是比创建一个空的DataFrame(或NaN之一)便宜,一次又一次地添加到列表中总是便宜的。列表还占用较少的内存,并且是用于,附加和删除(如果需要)的较轻的数据结构。
此方法的另一个优点是dtypes
可以自动推断(而不是分配object
给所有对象)。
最后一个优点是为您的数据自动创建了aRangeIndex
,因此不必担心(只需查看下面的劣势append
和loc
方法,您将在两种方法中看到需要正确处理索引的元素)。
append
或concat
在循环内这是我从初学者看到的最大错误:
df = pd.DataFrame(columns=['A', 'B', 'C'])
for a, b, c in some_function_that_yields_data():
df = df.append({'A': i, 'B': b, 'C': c}, ignore_index=True) # yuck
# or similarly,
# df = pd.concat([df, pd.Series({'A': i, 'B': b, 'C': c})], ignore_index=True)
Run Code Online (Sandbox Code Playgroud)
内存重新分配给每一个append
或concat
你有操作。再加上一个循环,就可以进行二次复杂度运算。从df.append
文档页面:
迭代地将行添加到DataFrame可能比单个连接更多地占用大量计算资源。更好的解决方案是将这些行添加到列表中,然后一次将列表与原始DataFrame连接起来。
与之相关的另一个错误df.append
是用户倾向于忘记append不是就地函数,因此必须将结果分配回去。您还必须担心dtypes:
df = pd.DataFrame(columns=['A', 'B', 'C'])
df = df.append({'A': 1, 'B': 12.3, 'C': 'xyz'}, ignore_index=True)
df.dtypes
A object # yuck!
B float64
C object
dtype: object
Run Code Online (Sandbox Code Playgroud)
处理对象列从来都不是一件好事,因为熊猫无法向量化这些列上的操作。您将需要执行以下操作来修复它:
df.infer_objects().dtypes
A int64
B float64
C object
dtype: object
Run Code Online (Sandbox Code Playgroud)
loc
循环内我还曾经看到过loc
将其追加到创建为空的DataFrame上:
df = pd.DataFrame(columns=['A', 'B', 'C'])
for a, b, c in some_function_that_yields_data():
df.loc[len(df)] = [a, b, c]
Run Code Online (Sandbox Code Playgroud)
和以前一样,您没有每次都预先分配所需的内存量,因此每次创建新行时都会重新增加内存。就像一样糟糕append
,甚至更难看。
然后,创建一个NaN的DataFrame以及与此相关的所有警告。
df = pd.DataFrame(columns=['A', 'B', 'C'], index=range(5))
df
A B C
0 NaN NaN NaN
1 NaN NaN NaN
2 NaN NaN NaN
3 NaN NaN NaN
4 NaN NaN NaN
Run Code Online (Sandbox Code Playgroud)
它会像其他对象一样创建一个对象列的DataFrame。
df.dtypes
A object # you DON'T want this
B object
C object
dtype: object
Run Code Online (Sandbox Code Playgroud)
如上所述,追加仍然存在所有问题。
for i, (a, b, c) in enumerate(some_function_that_yields_data()):
df.iloc[i] = [a, b, c]
Run Code Online (Sandbox Code Playgroud)
对这些方法进行计时是最快的方法,以了解它们在内存和实用性方面的差异。
归档时间: |
|
查看次数: |
1045398 次 |
最近记录: |