web-dev-qa-db-fra.com

Utilisation de pandas .append into for loop

J'ajoute des lignes à un pandas DataFrame dans une boucle for, mais à la fin, le cadre de données est toujours vide. Je ne souhaite pas ajouter les lignes à un tableau, puis appeler le constructeur DataFrame. , parce que ma boucle for actuelle traite beaucoup de données. J’ai aussi essayé sans succès pd.concat. Quelqu'un pourrait-il souligner ce qui me manque pour que l’instruction append fonctionne? Voici un exemple factice:

import pandas as pd
import numpy as np

data = pd.DataFrame([])

for i in np.arange(0, 4):
    if i % 2 == 0:
        data.append(pd.DataFrame({'A': i, 'B': i + 1}, index=[0]), ignore_index=True)
    else:
        data.append(pd.DataFrame({'A': i}, index=[0]), ignore_index=True)

print data.head()

Empty DataFrame
Columns: []
Index: []
[Finished in 0.676s]
22
calpyte

Vous devez définir la variable data égale au cadre de données ajouté. Contrairement à la méthode append sur un python, énumérez-la pandas append ne s'est pas produite)

import pandas as pd
import numpy as np

data = pd.DataFrame([])

for i in np.arange(0, 4):
    if i % 2 == 0:
        data = data.append(pd.DataFrame({'A': i, 'B': i + 1}, index=[0]), ignore_index=True)
    else:
        data = data.append(pd.DataFrame({'A': i}, index=[0]), ignore_index=True)

print(data.head())

   A    B
0  0  1.0
1  2  3.0
2  3  NaN
15
johnchase

Chaque fois que vous appelez append, Pandas renvoie une copie du bloc de données d'origine ainsi que votre nouvelle ligne. Cette opération est appelée copie quadratique. Il s'agit d'une opération O (N ^ 2) qui deviendra rapidement très difficile. lent (surtout depuis que vous avez beaucoup de données).

Dans votre cas, je vous recommanderais d'utiliser des listes, de les y ajouter, puis d'appeler le constructeur dataframe.

a_list = []
b_list = []
for data in my_data:
    a, b = process_data(data)
    a_list.append(a)
    b_list.append(b)
df = pd.DataFrame({'A': a_list, 'B': b_list})
del a_list, b_list

Timings

%%timeit
data = pd.DataFrame([])
for i in np.arange(0, 10000):
    if i % 2 == 0:
        data = data.append(pd.DataFrame({'A': i, 'B': i + 1}, index=[0]), ignore_index=True)
else:
    data = data.append(pd.DataFrame({'A': i}, index=[0]), ignore_index=True)
1 loops, best of 3: 6.8 s per loop

%%timeit
a_list = []
b_list = []
for i in np.arange(0, 10000):
    if i % 2 == 0:
        a_list.append(i)
        b_list.append(i + 1)
    else:
        a_list.append(i)
        b_list.append(None)
data = pd.DataFrame({'A': a_list, 'B': b_list})
100 loops, best of 3: 8.54 ms per loop
30
Alexander

Vous pouvez construire votre dataframe sans boucle:

n = 4
data = pd.DataFrame({'A': np.arange(n)})
data['B'] = np.NaN
data.loc[data['A'] % 2 == 0, 'B'] = data['A'] + 1

Pour:

n = 10000

C'est un peu plus rapide:

%%timeit
data = pd.DataFrame({'A': np.arange(n)})
data['B'] = np.NaN
data.loc[data['A'] % 2 == 0, 'B'] = data['A'] + 1

100 loops, best of 3: 3.3 ms per loop

vs.

%%timeit
a_list = []
b_list = []
for i in np.arange(n):
    if i % 2 == 0:
        a_list.append(i)
        b_list.append(i + 1)
    else:
        a_list.append(i)
        b_list.append(None)
data1 = pd.DataFrame({'A': a_list, 'B': b_list})

100 loops, best of 3: 12.4 ms per loop
2
Mike Müller