Add one row to pandas DataFrame
我知道Pandas是为加载完全填充的
我成功地创建了一个空数据帧,其中包含:
1 | res = DataFrame(columns=('lib', 'qty1', 'qty2')) |
然后我可以添加新行并用以下内容填充字段:
1 | res = res.set_value(len(res), 'qty1', 10.0) |
它可以工作,但看起来很奇怪:-/(它不能添加字符串值)
如何将新行添加到我的数据框架(具有不同的列类型)?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | >>> 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 |
如果您可以预先获得数据帧的所有数据,那么有一种比附加到数据帧更快的方法:
我有一个类似的任务,一行一行地附加到一个数据帧需要30分钟,然后从几秒钟内完成的字典列表中创建一个数据帧。
1 2 3 4 5 6 7 8 9 10 11 | 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) |
您可以使用
如果您事先知道条目数,则还应通过提供索引(以不同答案的数据为例)来预先分配空间:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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 |
速度比较
1 2 3 4 | 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 |
从评论中可以看出,6000码的速度差更大:
Increasing the size of the array (12) and the number of rows (500) makes
the speed difference more striking: 313ms vs 2.29s
要获得有效的附加,请参阅如何向熊猫数据帧中添加额外的行,并使用放大设置。
通过
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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 |
或:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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 |
1 2 3 4 5 | mycolumns = ['A', 'B'] df = pd.DataFrame(columns=mycolumns) rows = [[1,2],[3,4],[5,6]] for row in rows: df.loc[len(df)] = row |
您可以使用
1 2 3 4 5 6 7 8 9 10 | >>> 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 |
已经很久了,但我也面临同样的问题。在这里找到了很多有趣的答案。所以我很困惑该用什么方法。
在向数据帧添加大量行的情况下,我对速度性能感兴趣。所以我尝试了三种最流行的方法并检查了它们的速度。
2019年使用新版本的软件包更新
速度性能结果(秒):
1 2 3 4 | Adding 1000 rows 5000 rows 10000 rows .append 0.69 3.37 6.77 .loc 0.73 3.87 8.14 dict 0.011 0.046 0.088 |
还感谢@krassowski提供有用的评论-我更新了代码。
所以我通过字典为自己添加了内容。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import pandas import numpy import time #%% del df1, df2, df3 numOfRows = 1000 startTime = time.perf_counter() df1 = pandas.DataFrame(numpy.random.randint(100, size=(5,5)), columns=['A', 'B', 'C', 'D', 'E']) for i in range( 1,numOfRows-4): df1 = df1.append( dict( (a,numpy.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) startTime = time.perf_counter() df2 = pandas.DataFrame(numpy.random.randint(100, size=(5,5)), columns=['A', 'B', 'C', 'D', 'E']) for i in range( 1,numOfRows): df2.loc[i] = numpy.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) startTime = time.perf_counter() row_list = [] for i in range (0,5): row_list.append(dict( (a,numpy.random.randint(100)) for a in ['A','B','C','D','E'])) for i in range( 1,numOfRows-4): dict1 = dict( (a,numpy.random.randint(100)) for a in ['A','B','C','D','E']) row_list.append(dict1) df3 = pandas.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(df3.shape) |
另外,我相信我的实现并不完美,也许还有一些优化。
为了用Python的方式,这里添加我的答案:
1 2 3 4 5 6 | 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 |
这不是OP问题的答案,而是一个玩具例子来说明@shikhardua的答案,在上面我发现非常有用。
虽然这个片段很小,但在实际数据中,我有1000行和许多列,我希望能够按不同的列分组,然后对多个标记列执行下面的统计。因此,一次建立一行数据帧的可靠方法是非常方便的。谢谢你@shikhardua!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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 : ',BaseData,' Analysed Data : ',AnalysedData) |
您还可以构建列表列表并将其转换为数据帧-
1 2 3 4 5 6 7 8 9 10 | import pandas as pd rows = [] columns = ['i','double','square'] for i in range(6): row = [i, i*2, i*i] rows.append(row) df = pd.DataFrame(rows, columns=columns) |
给
1 2 3 4 5 6 7 | 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 |
想出一个简单而好的方法:
1 2 3 4 5 6 7 8 | >>> 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 |
创建新记录(数据帧)并添加到旧的数据帧。传递值列表和相应的列名以创建新的记录(数据帧)
1 2 3 | 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]) |
以下是在熊猫数据框中添加/附加行的方法
1 2 3 4 5 6 | def add_row(df, row): df.loc[-1] = row df.index = df.index + 1 return df.sort_index() add_row(df, [1,2,3]) |
它可用于在空的或填充的熊猫数据框中插入/附加行。
另一种方法(可能不是很有效):
1 2 3 4 5 6 | # add a row def add_row(df, row): colnames = list(df.columns) ncol = len(colnames) assert ncol == len(row),"Length of row must be the same as width of DataFrame: %s" % row return df.append(pd.DataFrame([row], columns=colnames)) |
您还可以像这样增强数据帧类:
1 2 3 4 | import pandas as pd def add_row(self, row): self.loc[len(self.index)] = row pd.DataFrame.add_row = add_row |
简单点。将列表作为输入,在数据框中作为行附加:
1 2 3 4 5 | import pandas as pd res = pd.DataFrame(columns=('lib', 'qty1', 'qty2')) for i in range(5): res_list = list(map(int, input().split())) res = res.append(pd.Series(res_list,index=['lib','qty1','qty2']), ignore_index=True) |
1 2 3 4 5 6 7 | import pandas as pd t1=pd.DataFrame() for i in range(len(the number of rows)): #add rows as columns t1[i]=list(rows) t1=t1.transpose() t1.columns=list(columns) |
这将负责向空数据帧添加项。问题是,对于第一个索引,df.index.max()==nan:
1 2 3 | 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)] |