Je commence à partir des documents pandas DataFrame ici: http://pandas.pydata.org/pandas-docs/stable/dsintro.html
Je voudrais remplir le DataFrame de manière itérative avec des valeurs dans un type de calcul de série chronologique. Donc, fondamentalement, je voudrais initialiser le DataFrame avec les colonnes A, B et les lignes d'horodatage, toutes 0 ou toutes NaN.
Je voudrais ensuite ajouter des valeurs initiales et passer en revue ces données en calculant la nouvelle ligne à partir de la ligne précédente, disons row[A][t] = row[A][t-1]+1
.
J'utilise actuellement le code ci-dessous, mais je pense que c'est un peu moche et il doit y avoir un moyen de le faire directement avec un DataFrame, ou tout simplement un meilleur moyen en général. Remarque: j'utilise Python 2.7.
import datetime as dt
import pandas as pd
import scipy as s
if __name__ == '__main__':
base = dt.datetime.today().date()
dates = [ base - dt.timedelta(days=x) for x in range(0,10) ]
dates.sort()
valdict = {}
symbols = ['A','B', 'C']
for symb in symbols:
valdict[symb] = pd.Series( s.zeros( len(dates)), dates )
for thedate in dates:
if thedate > dates[0]:
for symb in valdict:
valdict[symb][thedate] = 1+valdict[symb][thedate - dt.timedelta(days=1)]
print valdict
.append
en pd et en ajoutant une liste? Je sais que.append
dans les pandas, tout le jeu de données est copié vers un nouvel objet ´, les pythons s'ajoutent-ils différemment?Réponses:
Voici quelques suggestions:
Utilisation
date_range
pour l'index:Remarque: nous pourrions créer un DataFrame vide (avec
NaN
s) simplement en écrivant:Pour effectuer ce type de calculs pour les données, utilisez un tableau numpy:
Par conséquent, nous pouvons créer le DataFrame:
la source
index
x0
dimensions (columns = []
) et d'attacher une colonne à chaque tour de boucle. Je veux diredf[col_name] = pandas.Series([...])
dans une boucle itérative à travers les noms de colonnes. Dans le premier cas, non seulement l'allocation de mémoire prend du temps, mais le remplacement des NaN par de nouvelles valeurs semble extrêmement lent.Si vous souhaitez simplement créer un bloc de données vide et le remplir ultérieurement avec des blocs de données entrants, essayez ceci:
Dans cet exemple, j'utilise ce document pandas pour créer un nouveau bloc de données, puis j'utilise append bloc de données, puis j'utilise pour écrire dans le newDF avec les données de oldDF.
Si je dois continuer à ajouter de nouvelles données dans ce nouveau FD à partir de plusieurs anciens FD, j'utilise simplement une boucle for pour itérer sur pandas.DataFrame.append ()
la source
append
(et de la même manièreconcat
) copie le jeu de données complet dans un nouvel objet à chaque fois, par conséquent, l'itération et l'ajout peuvent et entraîneront un impact majeur sur les performances. pour plus d'informations, reportez-vous à: pandas.pydata.org/pandas-docs/stable/merging.htmlLa bonne façon ™ de créer un DataFrame
La plupart des réponses ici vous diront comment créer un DataFrame vide et le remplir, mais personne ne vous dira que c'est une mauvaise chose à faire.
Voici mon conseil: attendez jusqu'à ce que vous soyez sûr d'avoir toutes les données dont vous avez besoin pour travailler. Utilisez une liste pour collecter vos données, puis initialisez un DataFrame lorsque vous êtes prêt.
Il est toujours moins coûteux d'ajouter à une liste et de créer un DataFrame en une seule fois que de créer un DataFrame vide (ou l'un des NaN) et de l'ajouter encore et encore. Les listes prennent également moins de mémoire et sont une structure de données beaucoup plus légère avec laquelle travailler , ajouter et supprimer (si nécessaire).
L'autre avantage de cette méthode est
dtypes
automatiquement déduit (plutôt que de les affecterobject
à tous).Le dernier avantage est que a
RangeIndex
est automatiquement créé pour vos données , c'est donc une chose de moins à s'inquiéter (jetez un œil aux pauvresappend
et auxloc
méthodes ci-dessous, vous verrez des éléments dans les deux qui nécessitent une gestion appropriée de l'index).Choses que vous ne devriez PAS faire
append
ou à l'concat
intérieur d'une boucleVoici la plus grosse erreur que j'ai vue des débutants:
La mémoire est réattribuée pour chaque
append
ouconcat
opération que vous avez. Ajoutez à cela une boucle et vous aurez une opération de complexité quadratique . Depuis ladf.append
page doc :L'autre erreur associée
df.append
est que les utilisateurs ont tendance à oublier que l' ajout n'est pas une fonction sur place , donc le résultat doit être attribué à nouveau. Vous devez également vous soucier des dtypes:Traiter des colonnes d'objets n'est jamais une bonne chose, car les pandas ne peuvent pas vectoriser les opérations sur ces colonnes. Vous devrez le faire pour le réparer:
loc
à l'intérieur d'une boucleJ'ai également vu
loc
utilisé pour ajouter à un DataFrame créé vide:Comme précédemment, vous n'avez pas pré-alloué la quantité de mémoire dont vous avez besoin à chaque fois, donc la mémoire est agrandie chaque fois que vous créez une nouvelle ligne . C'est aussi mauvais que
append
et encore plus laid.Cadre de données vide de NaNs
Et puis, il y a la création d'un DataFrame de NaNs, et toutes les mises en garde qui y sont associées.
Il crée un DataFrame de colonnes d'objets, comme les autres.
L'ajout a toujours tous les problèmes comme les méthodes ci-dessus.
La preuve est dans le pudding
La synchronisation de ces méthodes est le moyen le plus rapide de voir à quel point elles diffèrent en termes de mémoire et d'utilité.
Code de référence pour référence.
la source
Initialiser un cadre vide avec des noms de colonne
Ajouter un nouvel enregistrement à un cadre
Vous pouvez également vouloir passer un dictionnaire:
Ajoutez un autre cadre à votre cadre existant
Considérations sur les performances
Si vous ajoutez des lignes dans une boucle, tenez compte des problèmes de performances. Pour les 1000 premiers enregistrements environ, les performances de "my_df.loc" sont meilleures, mais elles ralentissent progressivement en augmentant le nombre d'enregistrements dans la boucle.
Si vous prévoyez de faire des minces dans une grande boucle (disons des enregistrements de 10M environ), il vaut mieux utiliser un mélange de ces deux; remplissez un cadre de données avec iloc jusqu'à ce que la taille atteigne environ 1000, puis ajoutez-le au cadre de données d'origine et videz le cadre de données temporaire. Cela augmenterait vos performances d'environ 10 fois.
la source
my_df = my_df.append(my_df2)
ne fonctionne pas pour moi sauf si je le préciseignore_index=True
.Supposons une trame de données avec 19 lignes
Conserver la colonne A comme constante
Garder la colonne b comme variable donnée par une boucle
Vous pouvez remplacer le premier x dans
pd.Series([x], index = [x])
n'importe quelle valeurla source