我如何创建一个空DataFrame,然后添加行,一个接一个?
我创建了一个空DataFrame:
df = pd.DataFrame(columns=('lib', 'qty1', 'qty2'))
然后我可以在最后添加一个新行,并填充一个字段:
df = df._set_value(index=len(df), col='qty1', value=10.0)
它一次只适用于一个领域。向df中添加新行有什么更好的方法?
我如何创建一个空DataFrame,然后添加行,一个接一个?
我创建了一个空DataFrame:
df = pd.DataFrame(columns=('lib', 'qty1', 'qty2'))
然后我可以在最后添加一个新行,并填充一个字段:
df = df._set_value(index=len(df), col='qty1', value=10.0)
它一次只适用于一个领域。向df中添加新行有什么更好的方法?
当前回答
这将负责向空DataFrame添加一个项。问题是对于第一个索引,df.index.max() == nan:
df = pd.DataFrame(columns=['timeMS', 'accelX', 'accelY', 'accelZ', 'gyroX', 'gyroY', 'gyroZ'])
df.loc[0 if math.isnan(df.index.max()) else df.index.max() + 1] = [x for x in range(7)]
其他回答
在向dataframe添加大量行的情况下,我对性能感兴趣。所以我尝试了四种最流行的方法,并检查了它们的速度。
性能
使用.append (NPE的答案) 使用。loc (fred的回答) 使用.loc预分配(FooBar的答案) 使用dict并最终创建DataFrame (ShikharDua的回答)
运行时结果(秒):
Approach | 1000 rows | 5000 rows | 10 000 rows |
---|---|---|---|
.append | 0.69 | 3.39 | 6.78 |
.loc without prealloc | 0.74 | 3.90 | 8.35 |
.loc with prealloc | 0.24 | 2.58 | 8.70 |
dict | 0.012 | 0.046 | 0.084 |
所以我自己用了加法法。
代码:
import pandas as pd
import numpy as np
import time
del df1, df2, df3, df4
numOfRows = 1000
# append
startTime = time.perf_counter()
df1 = pd.DataFrame(np.random.randint(100, size=(5,5)), columns=['A', 'B', 'C', 'D', 'E'])
for i in range( 1,numOfRows-4):
df1 = df1.append( dict( (a,np.random.randint(100)) for a in ['A','B','C','D','E']), ignore_index=True)
print('Elapsed time: {:6.3f} seconds for {:d} rows'.format(time.perf_counter() - startTime, numOfRows))
print(df1.shape)
# .loc w/o prealloc
startTime = time.perf_counter()
df2 = pd.DataFrame(np.random.randint(100, size=(5,5)), columns=['A', 'B', 'C', 'D', 'E'])
for i in range( 1,numOfRows):
df2.loc[i] = np.random.randint(100, size=(1,5))[0]
print('Elapsed time: {:6.3f} seconds for {:d} rows'.format(time.perf_counter() - startTime, numOfRows))
print(df2.shape)
# .loc with prealloc
df3 = pd.DataFrame(index=np.arange(0, numOfRows), columns=['A', 'B', 'C', 'D', 'E'] )
startTime = time.perf_counter()
for i in range( 1,numOfRows):
df3.loc[i] = np.random.randint(100, size=(1,5))[0]
print('Elapsed time: {:6.3f} seconds for {:d} rows'.format(time.perf_counter() - startTime, numOfRows))
print(df3.shape)
# dict
startTime = time.perf_counter()
row_list = []
for i in range (0,5):
row_list.append(dict( (a,np.random.randint(100)) for a in ['A','B','C','D','E']))
for i in range( 1,numOfRows-4):
dict1 = dict( (a,np.random.randint(100)) for a in ['A','B','C','D','E'])
row_list.append(dict1)
df4 = pd.DataFrame(row_list, columns=['A','B','C','D','E'])
print('Elapsed time: {:6.3f} seconds for {:d} rows'.format(time.perf_counter() - startTime, numOfRows))
print(df4.shape)
附注:我相信我的实现并不完美,也许还有一些优化可以做。
我们经常看到结构df。loc[下标]=…分配给一个数据帧行。Mikhail_Sam发布了包含这个构造以及使用dict并最终创建DataFrame的方法的基准测试。他发现后者是目前为止最快的。
但是如果我们替换df3。loc[i] =…(与预分配的DataFrame)在他的代码df3。值[i] =…时,结果会发生显著变化,因为该方法的执行与使用dict的方法类似。所以我们应该经常使用df。考虑[下标]=…但是请注意,.values有一个从零开始的下标,这可能与DataFrame.index不同。
有关有效附加,请参见如何向pandas数据框架添加额外行和使用放大设置。
通过loc/ix在不存在的键索引数据上添加行。例如:
In [1]: se = pd.Series([1,2,3])
In [2]: se
Out[2]:
0 1
1 2
2 3
dtype: int64
In [3]: se[5] = 5.
In [4]: se
Out[4]:
0 1.0
1 2.0
2 3.0
5 5.0
dtype: float64
Or:
In [1]: dfi = pd.DataFrame(np.arange(6).reshape(3,2),
.....: columns=['A','B'])
.....:
In [2]: dfi
Out[2]:
A B
0 0 1
1 2 3
2 4 5
In [3]: dfi.loc[:,'C'] = dfi.loc[:,'A']
In [4]: dfi
Out[4]:
A B C
0 0 1 0
1 2 3 2
2 4 5 4
In [5]: dfi.loc[3] = 5
In [6]: dfi
Out[6]:
A B C
0 0 1 0
1 2 3 2
2 4 5 4
3 5 5 5
可以使用ignore_index选项将单行追加为字典。
>>> f = pandas.DataFrame(data = {'Animal':['cow','horse'], 'Color':['blue', 'red']})
>>> f
Animal Color
0 cow blue
1 horse red
>>> f.append({'Animal':'mouse', 'Color':'black'}, ignore_index=True)
Animal Color
0 cow blue
1 horse red
2 mouse black
下面是在Pandas数据框架中添加/追加一行的方法:
def add_row(df, row):
df.loc[-1] = row
df.index = df.index + 1
return df.sort_index()
add_row(df, [1,2,3])
它可以用于在空的或填充的Pandas数据框架中插入/追加一行。