web-dev-qa-db-fra.com

Insérer une ligne dans pandas _ dataframe

J'ai une base de données ..

s1 = pd.Series([5, 6, 7])
s2 = pd.Series([7, 8, 9])

df = pd.DataFrame([list(s1), list(s2)],  columns =  ["A", "B", "C"])

   A  B  C
0  5  6  7
1  7  8  9

[2 rows x 3 columns]

et je dois ajouter une première ligne [2, 3, 4] pour obtenir ..

   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9

J'ai essayé les fonctions append () et concat (), mais je n'arrive pas à trouver le bon moyen de le faire.

Des idées? Existe-t-il un moyen direct d'ajouter/insérer des séries dans le cadre de données?

88
Meloun

Assignez simplement la ligne à un index particulier, en utilisant loc:

 df.loc[-1] = [2, 3, 4]  # adding a row
 df.index = df.index + 1  # shifting index
 df = df.sort_index()  # sorting by index

Et vous obtenez, comme vous le souhaitez:

    A  B  C
 0  2  3  4
 1  5  6  7
 2  7  8  9

Voir dans Pandas _ documentation Indexation: Réglage avec agrandissement .

113
Piotr Migdal

Une façon d'y parvenir est

>>> pd.DataFrame(np.array([[2, 3, 4]]), columns=['A', 'B', 'C']).append(df, ignore_index=True)
Out[330]: 
   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9

En général, il est plus facile d’ajouter des images de données, et non des séries. Dans votre cas, puisque vous voulez que la nouvelle ligne soit "en haut" (avec l'identifiant de départ) et qu'il n'y ait pas de fonction pd.prepend(), je crée d'abord le nouveau cadre de données, puis ajoute l'ancien.

ignore_index ignorera l'ancien index en cours dans votre cadre de données et veillera à ce que la première ligne commence réellement par l'index 1 au lieu de redémarrer avec l'index 0.

Disclaimer typique: Cetero censeo ... l'ajout de lignes est une opération assez inefficace. Si vous vous souciez de la performance et que vous pouvez d'une manière ou d'une autre vous assurer de créer tout d'abord une trame de données avec le bon index (plus long), puis simplement insertion la ligne supplémentaire dans la trame de données, vous devriez certainement le faire. Voir:

>>> index = np.array([0, 1, 2])
>>> df2 = pd.DataFrame(columns=['A', 'B', 'C'], index=index)
>>> df2.loc[0:1] = [list(s1), list(s2)]
>>> df2
Out[336]: 
     A    B    C
0    5    6    7
1    7    8    9
2  NaN  NaN  NaN
>>> df2 = pd.DataFrame(columns=['A', 'B', 'C'], index=index)
>>> df2.loc[1:] = [list(s1), list(s2)]

Jusqu'ici, nous avons ce que vous aviez comme df:

>>> df2
Out[339]: 
     A    B    C
0  NaN  NaN  NaN
1    5    6    7
2    7    8    9

Mais maintenant, vous pouvez facilement insérer la ligne comme suit. Depuis que l'espace a été préalloué, ceci est plus efficace.

>>> df2.loc[0] = np.array([2, 3, 4])
>>> df2
Out[341]: 
   A  B  C
0  2  3  4
1  5  6  7
2  7  8  9
18
FooBar

Vous ne savez pas comment vous appelez concat () mais cela devrait fonctionner tant que les deux objets sont du même type. Peut-être que le problème est que vous devez convertir votre deuxième vecteur dans un cadre de données? En utilisant le df que vous avez défini ce qui suit fonctionne pour moi.

>>>df2 = pd.DataFrame([[2,3,4]],columns=['A','B','C'])
>>>pd.concat([df2,df])
15
mgilbert

J'ai assemblé une fonction courte qui permet un peu plus de flexibilité lors de l'insertion d'une ligne:

def insert_row(idx, df, df_insert):
    dfA = df.iloc[:idx, ]
    dfB = df.iloc[idx:, ]

    df = dfA.append(df_insert).append(dfB).reset_index(drop = True)

    return df

qui pourrait être réduit à:

def insert_row(idx, df, df_insert):
    return df.iloc[:idx, ].append(df_insert).append(df.iloc[idx:, ]).reset_index(drop = True)

Ensuite, vous pouvez utiliser quelque chose comme:

df = insert_row(2, df, df_new)

2 est la position d'index dans df où vous souhaitez insérer df_new.

8
elPastor

Nous pouvons utiliser numpy.insert . Cela a l'avantage de la flexibilité. Il vous suffit de spécifier l'index que vous souhaitez insérer.

_s1 = pd.Series([5, 6, 7])
s2 = pd.Series([7, 8, 9])

df = pd.DataFrame([list(s1), list(s2)],  columns =  ["A", "B", "C"])

pd.DataFrame(np.insert(df.values, 0, values=[2, 3, 4], axis=0))

    0   1   2
0   2   3   4
1   5   6   7
2   7   8   9
_

Pour np.insert(df.values, 0, values=[2, 3, 4], axis=0), 0 indique à la fonction l'emplacement/l'index dans lequel vous souhaitez placer les nouvelles valeurs.

5
Tai

Ci-dessous, le meilleur moyen d'insérer une ligne dans pandas dataframe sans trier et réinitialiser un index:

import pandas as pd
import numpy as np

df = pd.DataFrame(columns=['a','b','c'])

def insert(df, row):
    insert_loc = df.index.max()

    if np.isnan(insert_loc):
        df.loc[0] = row
    else:
        df.loc[insert_loc + 1] = row

insert(df,[2,3,4])
insert(df, [8,9,0])
print(df)
4
Sagar Rathod

cela peut sembler excessivement simple, mais il est incroyable qu’une simple fonction d’insertion de nouvelle ligne ne soit pas intégrée. J'ai beaucoup lu sur l’ajout d’un nouveau fichier DF à l’original, mais je me demande si ce serait plus rapide.

df.loc[0] = [row1data, blah...]
i = len(df) + 1
df.loc[i] = [row2data, blah...]
2
Aaron Melgar