PhE*_*PhE 731 python append dataframe pandas
我知道pandas旨在加载完全填充DataFrame但我需要创建一个空的DataFrame,然后逐个添加行.做这个的最好方式是什么 ?
我成功创建了一个空的DataFrame:
res = DataFrame(columns=('lib', 'qty1', 'qty2'))
Run Code Online (Sandbox Code Playgroud)
然后我可以添加一个新行并填充一个字段:
res = res.set_value(len(res), 'qty1', 10.0)
Run Code Online (Sandbox Code Playgroud)
它工作但似乎很奇怪: - /(它添加字符串值失败)
如何向我的DataFrame添加新行(具有不同的列类型)?
fre*_*red 466
>>> import pandas as pd
>>> from numpy.random import randint
>>> df = pd.DataFrame(columns=['lib', 'qty1', 'qty2'])
>>> for i in range(5):
>>> df.loc[i] = ['name' + str(i)] + list(randint(10, size=2))
>>> df
lib qty1 qty2
0 name0 3 3
1 name1 2 4
2 name2 2 8
3 name3 2 1
4 name4 9 6
Run Code Online (Sandbox Code Playgroud)
Shi*_*Dua 378
如果您可以预先获取数据帧的所有数据,则可以采用比附加到数据框更快的方法:
我有一个类似的任务,逐行追加数据框需要30分钟,并在几秒钟内完成一个字典列表中的数据框.
rows_list = []
for row in input_rows:
dict1 = {}
# get input row in dictionary format
# key = col_name
dict1.update(blah..)
rows_list.append(dict1)
df = pd.DataFrame(rows_list)
Run Code Online (Sandbox Code Playgroud)
NPE*_*NPE 265
你可以使用pandas.concat()或DataFrame.append().有关详细信息和示例,请参阅合并,连接和连接.
cs9*_*s95 174
是的,人们已经解释过你永远不应该增长一个 DataFrame,你应该将你的数据附加到一个列表中,并在最后一次将它转换为一个 DataFrame。但是你明白为什么吗?
以下是最重要的原因,摘自我在这里的帖子。
dtypes自动推断您的数据。另一方面,创建一个空的 NaN 框架会自动使它们成为object,这很糟糕。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)
append或concat在循环内
append并且在孤立的情况下concat本质上并不坏。当您在循环内迭代调用它们时,问题就开始了 - 这会导致二次内存使用。
# Creates empty DataFrame and appends
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)
# This is equally bad:
# df = pd.concat(
# [df, pd.Series({'A': i, 'B': b, 'C': c})],
# ignore_index=True)
Run Code Online (Sandbox Code Playgroud)
NaN 的空数据帧
永远不要创建 NaN 的 DataFrame,因为列是用object(慢的、不可矢量化的 dtype)初始化的
。
# Creates DataFrame of NaNs and overwrites values.
df = pd.DataFrame(columns=['A', 'B', 'C'], index=range(5))
for a, b, c in some_function_that_yields_data():
df.loc[len(df)] = [a, b, c]
Run Code Online (Sandbox Code Playgroud)
对这些方法进行计时是查看它们在内存和效用方面有多大差异的最快方法。
像这样的帖子提醒我为什么我是这个社区的一员。人们理解教人们用正确的代码得到正确答案的重要性,而不是用错误的代码得到正确的答案。现在您可能会争辩说这不是问题,loc或者append您是否只向 DataFrame 添加一行。然而,人们往往看这个问题补充不止一个行-通常要求是反复添加使用来自一个函数的数据在一个循环内一排(见相关的问题)。在这种情况下,重要的是要了解迭代增长 DataFrame 不是一个好主意。
Mik*_*Sam 131
已经很久了,但我也遇到了同样的问题.并在这里找到了很多有趣的答案.所以我很困惑使用什么方法.
在向数据帧添加大量行的情况下,我对速度性能感兴趣.所以我尝试了3种最流行的方法并检查了它们的速度.
使用新版本的软件包在2019年更新
结果(以秒为单位):
|------------|-------------|-------------|-------------|
| Approach | 1000 rows | 5000 rows | 10 000 rows |
|------------|-------------|-------------|-------------|
| .append | 0.69 | 3.39 | 6.78 |
|------------|-------------|-------------|-------------|
| .loc w/o | 0.74 | 3.90 | 8.35 |
| prealloc | | | |
|------------|-------------|-------------|-------------|
| .loc with | 0.24 | 2.58 | 8.70 |
| prealloc | | | |
|------------|-------------|-------------|-------------|
| dict | 0.012 | 0.046 | 0.084 |
|------------|-------------|-------------|-------------|
Run Code Online (Sandbox Code Playgroud)
还要感谢@krassowski的有用评论 - 我更新了代码.
所以我通过字典为自己添加了.
码:
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)
Run Code Online (Sandbox Code Playgroud)
PS我相信,我的认识并不完美,也许有一些优化.
Foo*_*Bar 96
如果您事先知道条目数,则应通过提供索引来预先分配空间(从不同答案中获取数据示例):
import pandas as pd
import numpy as np
# we know we're gonna have 5 rows of data
numberOfRows = 5
# create dataframe
df = pd.DataFrame(index=np.arange(0, numberOfRows), columns=('lib', 'qty1', 'qty2') )
# now fill it up row by row
for x in np.arange(0, numberOfRows):
#loc or iloc both work here since the index is natural numbers
df.loc[x] = [np.random.randint(-1,1) for n in range(3)]
In[23]: df
Out[23]:
lib qty1 qty2
0 -1 -1 -1
1 0 0 0
2 -1 0 -1
3 0 -1 0
4 -1 0 0
Run Code Online (Sandbox Code Playgroud)
速度比较
In[30]: %timeit tryThis() # function wrapper for this answer
In[31]: %timeit tryOther() # function wrapper without index (see, for example, @fred)
1000 loops, best of 3: 1.23 ms per loop
100 loops, best of 3: 2.31 ms per loop
Run Code Online (Sandbox Code Playgroud)
而且 - 从评论中 - 大小为6000,速度差异变得更大:
增加阵列(12)的大小和行数(500)会使速度差异更加显着:313ms vs 2.29s
Lyd*_*dia 69
mycolumns = ['A', 'B']
df = pd.DataFrame(columns=mycolumns)
rows = [[1,2],[3,4],[5,6]]
for row in rows:
df.loc[len(df)] = row
Run Code Online (Sandbox Code Playgroud)
Nas*_*ibi 67
有效追加请参阅如何向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
Run Code Online (Sandbox Code Playgroud)
要么:
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
Run Code Online (Sandbox Code Playgroud)
W.P*_*ill 57
您可以使用该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
Run Code Online (Sandbox Code Playgroud)
hky*_*kyi 41
为了Pythonic的方式,这里添加我的答案:
res = pd.DataFrame(columns=('lib', 'qty1', 'qty2'))
res = res.append([{'qty1':10.0}], ignore_index=True)
print(res.head())
lib qty1 qty2
0 NaN 10.0 NaN
Run Code Online (Sandbox Code Playgroud)
Bri*_*rns 19
您还可以构建列表列表并将其转换为数据框 -
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)
Run Code Online (Sandbox Code Playgroud)
给
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
小智 14
这不是OP问题的答案,而是一个玩具示例来说明@ShikharDua的答案,我发现它非常有用.
虽然这个片段是微不足道的,但在实际数据中我有1,000行和多列,我希望能够按不同的列进行分组,然后对多个taget列执行下面的统计.因此,一次一行地构建数据帧的可靠方法是非常方便的.谢谢@ShikharDua!
import pandas as pd
BaseData = pd.DataFrame({ 'Customer' : ['Acme','Mega','Acme','Acme','Mega','Acme'],
'Territory' : ['West','East','South','West','East','South'],
'Product' : ['Econ','Luxe','Econ','Std','Std','Econ']})
BaseData
columns = ['Customer','Num Unique Products', 'List Unique Products']
rows_list=[]
for name, group in BaseData.groupby('Customer'):
RecordtoAdd={} #initialise an empty dict
RecordtoAdd.update({'Customer' : name}) #
RecordtoAdd.update({'Num Unique Products' : len(pd.unique(group['Product']))})
RecordtoAdd.update({'List Unique Products' : pd.unique(group['Product'])})
rows_list.append(RecordtoAdd)
AnalysedData = pd.DataFrame(rows_list)
print('Base Data : \n',BaseData,'\n\n Analysed Data : \n',AnalysedData)
Run Code Online (Sandbox Code Playgroud)
Qin*_*nsi 13
想出一个简单而好的方法:
>>> 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
Run Code Online (Sandbox Code Playgroud)
Roc*_*tar 10
您可以使用生成器对象来创建数据帧,这将比列表更节省内存。
num = 10
# Generator function to generate generator object
def numgen_func(num):
for i in range(num):
yield ('name_{}'.format(i), (i*i), (i*i*i))
# Generator expression to generate generator object (Only once data get populated, can not be re used)
numgen_expression = (('name_{}'.format(i), (i*i), (i*i*i)) for i in range(num) )
df = pd.DataFrame(data=numgen_func(num), columns=('lib', 'qty1', 'qty2'))
Run Code Online (Sandbox Code Playgroud)
要将原始数据添加到现有 DataFrame,您可以使用 append 方法。
df = df.append([{ 'lib': "name_20", 'qty1': 20, 'qty2': 400 }])
Run Code Online (Sandbox Code Playgroud)
创建一个新记录(数据框)并添加到old_data_frame.
传递值列表和相应的列名以创建new_record(data_frame)
new_record = pd.DataFrame([[0,'abcd',0,1,123]],columns=['a','b','c','d','e'])
old_data_frame = pd.concat([old_data_frame,new_record])
Run Code Online (Sandbox Code Playgroud)
与ShikharDua 的回答中的字典列表不同,我们还可以将我们的表表示为列表字典,其中每个列表按行顺序存储一列,前提是我们事先知道我们的列。最后我们构造我们的 DataFrame 一次。
对于c列和n行,这使用一个字典和c 个列表,而不是一个列表和n 个字典。list-of-dictionaries 方法让每个字典存储所有键,并且需要为每一行创建一个新字典。这里我们只附加到列表,这是恒定的时间,理论上非常快。
# Current data
data = {"Animal":["cow", "horse"], "Color":["blue", "red"]}
# Adding a new row (be careful to ensure every column gets another value)
data["Animal"].append("mouse")
data["Color"].append("black")
# At the end, construct our DataFrame
df = pd.DataFrame(data)
# Animal Color
# 0 cow blue
# 1 horse red
# 2 mouse black
Run Code Online (Sandbox Code Playgroud)
小智 5
这是在熊猫DataFrame中添加/添加行的方法
def add_row(df, row):
df.loc[-1] = row
df.index = df.index + 1
return df.sort_index()
add_row(df, [1,2,3])
Run Code Online (Sandbox Code Playgroud)
它可以用于在空的或填充的熊猫DataFrame中插入/追加一行
| 归档时间: |
|
| 查看次数: |
1076557 次 |
| 最近记录: |