1. ホーム
  2. python

[解決済み] pandas dataframeの行をforループで追加するには?

2023-03-17 07:42:52

質問

以下のようなforループがあります。

for i in links:
     data = urllib2.urlopen(str(i)).read()
     data = json.loads(data)
     data = pd.DataFrame(data.items())
     data = data.transpose()
     data.columns = data.iloc[0]
     data = data.drop(data.index[[0]])

このようにして作成された各データフレームは、ほとんどの列が他のものと共通していますが、すべての列が共通というわけではありません。さらに、それらはすべて1行だけを持っています。私が必要とするのは、forループによって生成された各データフレームから、すべての異なる列と各行をデータフレームに追加することです。

私はpandas concatenateまたは同様のものを試しましたが、何も動作しないようです。何かアイデアはありますか?ありがとうございます。

どのように解決するのですか?

あなたのデータがこのようなものだったとします。

import pandas as pd
import numpy as np

np.random.seed(2015)
df = pd.DataFrame([])
for i in range(5):
    data = dict(zip(np.random.choice(10, replace=False, size=5),
                    np.random.randint(10, size=5)))
    data = pd.DataFrame(data.items())
    data = data.transpose()
    data.columns = data.iloc[0]
    data = data.drop(data.index[[0]])
    df = df.append(data)
print('{}\n'.format(df))
# 0   0   1   2   3   4   5   6   7   8   9
# 1   6 NaN NaN   8   5 NaN NaN   7   0 NaN
# 1 NaN   9   6 NaN   2 NaN   1 NaN NaN   2
# 1 NaN   2   2   1   2 NaN   1 NaN NaN NaN
# 1   6 NaN   6 NaN   4   4   0 NaN NaN NaN
# 1 NaN   9 NaN   9 NaN   7   1   9 NaN NaN

であれば、次のように置き換えることができる。

np.random.seed(2015)
data = []
for i in range(5):
    data.append(dict(zip(np.random.choice(10, replace=False, size=5),
                         np.random.randint(10, size=5))))
df = pd.DataFrame(data)
print(df)

つまり、各行ごとに新しいDataFrameを作成するのではなく、すべてのデータをdictsのリストに集めてから、DataFrameを呼び出します。その代わり、全てのデータをdictsのリストに集め、その中から df = pd.DataFrame(data) を最後に一度だけ呼び出します。

の各呼び出しは df.append を呼び出すたびに、1行増えた新しいDataFrameのための領域を確保し、元のDataFrameから新しいDataFrameにすべてのデータをコピーし、さらに新しい行にデータをコピーする必要があります。このような割り当てとコピーにより df.append をループで呼び出すことは非常に非効率的です。コピーにかかる時間的コストは は二次関数的に増大します。 のコピーにかかる時間は、行の数に対して二次関数的に増加します。call-DataFrame-onceのコードは書きやすいだけでなく、性能もずっと良くなります。コピーにかかる時間は行の数に対して直線的に増加します。