我如何创建一个空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中添加新行有什么更好的方法?
当前回答
您还可以建立一个列表的列表,并将其转换为数据框架-
import pandas as pd
columns = ['i','double','square']
rows = []
for i in range(6):
row = [i, i*2, i*i]
rows.append(row)
df = pd.DataFrame(rows, columns=columns)
给
i double square 0 0 0 0 1 1 2 1 2 2 4 4 3 3 6 9 4 4 8 16 5 5 10 25
其他回答
initial_data = {'lib': np.array([1,2,3,4]), 'qty1': [1,2,3,4], 'qty2': [1,2,3,4]}
df = pd.DataFrame(initial_data)
df
lib qty1 qty2
0 1 1 1
1 2 2 2
2 3 3 3
3 4 4 4
val_1 = [10]
val_2 = [14]
val_3 = [20]
df.append(pd.DataFrame({'lib': val_1, 'qty1': val_2, 'qty2': val_3}))
lib qty1 qty2
0 1 1 1
1 2 2 2
2 3 3 3
3 4 4 4
0 10 14 20
可以使用for循环遍历值,也可以添加值数组。
val_1 = [10, 11, 12, 13]
val_2 = [14, 15, 16, 17]
val_3 = [20, 21, 22, 43]
df.append(pd.DataFrame({'lib': val_1, 'qty1': val_2, 'qty2': val_3}))
lib qty1 qty2
0 1 1 1
1 2 2 2
2 3 3 3
3 4 4 4
0 10 14 20
1 11 15 21
2 12 16 22
3 13 17 43
如果你总是想在最后添加一个新行,使用这个:
df.loc[len(df)] = ['name5', 9, 0]
我想出了一个简单而美好的方法:
>>> df
A B C
one 1 2 3
>>> df.loc["two"] = [4,5,6]
>>> df
A B C
one 1 2 3
two 4 5 6
请注意评论中提到的性能警告。
你可以使用pandas.concat()。有关详细信息和示例,请参见合并、连接和连接。
例如:
def append_row(df, row):
return pd.concat([
df,
pd.DataFrame([row], columns=row.index)]
).reset_index(drop=True)
df = pd.DataFrame(columns=('lib', 'qty1', 'qty2'))
new_row = pd.Series({'lib':'A', 'qty1':1, 'qty2': 2})
df = append_row(df, new_row)
在向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)
附注:我相信我的实现并不完美,也许还有一些优化可以做。