web-dev-qa-db-ja.com

パンダDataFrameに1行追加する

私はパンダが完全に移入されたDataFrameをロードするように設計されていることを理解していますが、私は 空のDataFrameを作成して行を一つずつ追加する必要があります 。これを行うための最良の方法は何ですか?

私は正常に空のDataFrameを作成しました:

res = DataFrame(columns=('lib', 'qty1', 'qty2'))

それから私は新しい行を追加してフィールドを埋めることができます:

res = res.set_value(len(res), 'qty1', 10.0)

それは動作しますが、非常に奇妙に思えます: - /(文字列値を追加するのに失敗しました)

DataFrameに新しい行を追加するにはどうすればよいですか(異なる列型を使用)。

624
PhE
>>> 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
400
fred

データフレームのすべてのデータを事前に取得できる場合は、データフレームに追加するよりもはるかに高速な方法があります。

  1. 各辞書が入力データ行に対応する辞書のリストを作成します。
  2. このリストからデータフレームを作成します。

行ごとにデータフレームを追加するのに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)               
317
ShikharDua

pandas.concat()またはDataFrame.append()を使うことができます。詳細と例については、 マージ、結合、および連結 を参照してください。

254
NPE

事前のエントリ数がわかっている場合は、インデックスも指定してスペースを事前に割り当てる必要があります(別の回答からのデータ例を参照)。

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

速度比較

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の場合、速度差はさらに大きくなります。

配列のサイズ(12)と行数(500)を大きくすると、速度差がより顕著になります。313ms対2.29s

85
FooBar

効率的な追加については、 パンダデータフレームに追加の行を追加する方法 および を参照してください。 .

存在しないキーインデックスデータに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

または

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
65
mycolumns = ['A', 'B']
df = pd.DataFrame(columns=mycolumns)
rows = [[1,2],[3,4],[5,6]]
for row in rows:
    df.loc[len(df)] = row
62
Lydia

それは長い時間でしたが、私も同じ問題に直面しました。そして、ここにたくさんの興味深い答えが見つかりました。だから私はどの方法を使うべきか混乱していました。

データフレームに大量の行を追加する場合は、スピードパフォーマンスのに興味があります。だから私は3つの最も人気のある方法を試してみて、それらのスピードをチェックしました。

2019年に更新新しいバージョンのパッケージを使用

スピードパフォーマンス

  1. .appendを使用する( NPEの答え
  2. .loc( フレッドの答えFooBarの答え )を使う
  3. 最後にdictを使ってDataFrameを作成する( ShikharDuaの答え

結果(秒):

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 の有用なコメントにも感謝します - コードを更新しました。

だから私は自分自身で辞書を通して加算を使います。


コード:

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)

P.S私の考えは完璧ではないし、最適化もあるかもしれません。

59
Mikhail_Sam

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
52
W.P. McNeill

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
37
hkyi

これはOPの質問に対する答えではなく、@ ShikharDuaの答えを説明するためのおもちゃの例です。

この断片は些細なことですが、実際のデータでは私は何千もの行と多くの列を持っていました、そして私は異なる列でグループ化して複数のtaget列に対して以下の統計を実行できることを望みました。そのため、一度に1行ずつデータフレームを構築するための信頼性の高い方法があると非常に便利でした。 @ 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)
13
user3250815

リストのリストを作成してそれをデータフレームに変換することもできます -

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)

与える

 i二重四角形
 0 0 0 0 
 1 1 2 1 
 2 2 4 4 
 3 3 6 9 
 4 4 8 16 
 5 5 10 25 
10
Brian Burns

シンプルでいい方法を考え出した:

>>> 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
8
Qinsi

新しいレコード(データフレーム)を作成し、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])
5
Jack Daniel

これはパンダ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]) 

空の、または移入されたパンダDataFrameに行を挿入/追加するために使用できます。

5
Shivam Agrawal

それを行う別の方法(おそらくそれほどパフォーマンスが良くない):

# 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))

このようにDataFrameクラスを拡張することもできます。

import pandas as pd
def add_row(self, row):
    self.loc[len(self.index)] = row
pd.DataFrame.add_row = add_row
3
qed

それを簡単に。データフレームの行として追加される入力としてリストを使用することによって: -

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
Vineet Jain
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)
0
Vicky

1つのDataFrame行に割り当てるための構成df.loc[subscript] = …がよく見られます。 Mikhail_Samが投稿しました ベンチマーク とりわけこのコンストラクトとdictを使用するメソッドを含み、最後にDataFrameを作成します。彼は後者が群を抜いて最速であることを発見した。ただし、彼のコードのdf3.loc[i] = …(事前に割り当てられたDataFrameを使用)をdf3.values[i] = …に置き換えると、結果は大幅に変わります。その方法はdictを使用する方法と同様に実行されます。そのため、df.values[subscript] = …の使用をより頻繁に考慮する必要があります。ただし、.valuesは、ゼロから始まる添字を使用することに注意してください。これは、DataFrame.indexとは異なる場合があります。

0
Armali