En truncate_before
:
def truncate_before(list_of_dfts, idx):
for dfts in list_of_dfts:
dfts = dfts[idx:]
print(dfts.head)
le for-loop
crée une variable locale dfts
qui fait référence à la DataFrames dans list_of_dfts
. Mais
dfts = dfts[idx:]
réaffecte une nouvelle valeur à dfts
. Il ne modifie pas le DataFrame dans list_of_dfts
.
Voir Facts and myths about Python names and values pour une excellente explication de la manière dont les noms de variables se lient aux valeurs, et quelles opérations modifient les valeurs par rapport aux nouvelles valeurs de liaison aux noms de variables.
Voici un certain nombre d'alternatives:
Modifier la liste inplace
def truncate_before(list_of_dfts, idx):
list_of_dfts[:] = [dfts[idx:] for dfts in list_of_dfts]
for dfts in list_of_dfts:
print(dfts.head)
depuis l'attribution à list_of_dfts[:]
(qui appelle list_of_dfts.__setitem__
) modifie le contenu de list_of_dfts
enplace.
import numpy as np
import pandas as pd
df_a = pd.DataFrame(np.random.rand(14,2), columns = list('XY'))
df_b = pd.DataFrame(np.random.rand(14,2), columns = list('XY'))
mylist = [df_a, df_b]
def truncate_before(list_of_dfts, idx):
list_of_dfts[:] = [dfts[idx:] for dfts in list_of_dfts]
print(mylist[0])
truncate_before(mylist, 11)
print(mylist[0])
montre mylist[0]
a été tronquée. Notez cependant que df_a
fait toujours référence au DataFrame d'origine.
Retour la liste et réassigner mylist
ou df_a, df_b
au résultat
L'utilisation de valeurs de retour peut rendre inutile de modifier mylist
en place.
À remaniera les variables globales df_a
, df_b
à une nouvelle valeur, vous pouvez faire truncate_before
retour la liste des DataFrames et réattribuer df_a
et df_b
à la valeur retournée:
def truncate_before(list_of_dfts, idx):
return [dfts[idx:] for dfts in list_of_dfts]
mylist = truncate_before(mylist, 11) # or
# df_a, df_b = truncate_before(mylist, 11) # or
# mylist = df_a, df_b = truncate_before(mylist, 11)
Mais attention qu'il n'est probablement pas bon d'accéder aux DataFrames à travers les deux mylist
et df_a
et df_b
, puisque comme l'exemple ci-dessus le montre, les valeurs ne restent pas coordonnées automatiquement magiquement.En utilisant mylist
devrait suffire.
utiliser une méthode de trame de données avec le paramètre inplace, comme df.drop
dfts.drop
(avec inplace=True
) modifie dfts
lui-même:
import numpy as np
import pandas as pd
df_a = pd.DataFrame(np.random.rand(14,2), columns = list('XY'))
df_b = pd.DataFrame(np.random.rand(14,2), columns = list('XY'))
mylist = [df_a, df_b]
def truncate_before(list_of_dfts, idx):
for dfts in list_of_dfts:
dfts.drop(dfts.index[:idx], inplace=True)
truncate_before(mylist, 11)
print(mylist[0])
print(df_a)
En modifiant dfts
inplace, à la fois les valeurs de mylist
etdf_a
et df_b
sont modifiés en même temps.
Notez que dfts.drop
supprime des lignes en fonction de la valeur d'étiquette d'index. Donc, ce qui précède repose sur (suppose) que dfts.index
est unique. Si dfts.index
n'est pas unique, dfts.drop
peut contenir plus de lignes que idx
lignes. Par exemple,
df = pd.DataFrame([1,2], index=['A', 'A'])
df.drop(['A'], inplace=True)
gouttes les deux rangées faisant df
un vide dataframe.
Notez également cet avertissement développeur de base de Pandas concernant l'utilisation de inplace
:
Mon opinion personnelle: Je ne jamais utiliser les opérations en place. La syntaxe est plus difficile à read et n'offre aucun avantage.
Ceci est probablement dû sous le capot, dfts.drop
crée une nouvelle trame de données et appelle ensuite la méthode privée _update_inplace
pour affecter les nouvelles données à l'ancienne dataframe :
def _update_inplace(self, result, verify_is_copy=True):
"""
replace self internals with result.
...
"""
self._reset_cache()
self._clear_item_cache()
self._data = getattr(result,'_data',result)
self._maybe_update_cacher(verify_is_copy=verify_is_copy)
Depuis le result
temporaire avait À créer de toute façon, il n'y a pas de bénéfice en termes de mémoire ou de performance des opérations «sur place» par rapport à une simple réaffectation.
Ok, mylist était une construction pour regrouper toutes les données individuelles. N'y a-t-il rien d'autre que je puisse faire en ce qui concerne les bases de données originales? Bien sûr, je pourrais juste le faire un par un. df_a = df_a [idx:], etc. Mais une manière programmatique serait bien. Laissez-moi finir de lire l'article que vous avez recommandé. – Spinor8
'df.drop (..., inplace = True)' modifie '' df' inplace, mais en raison de la façon dont les opérations inplace sont implémentées dans Pandas, il n'y a aucun avantage réel à le faire par rapport à la réaffectation plus directe vers noms de variables. Personnellement, je préfère les fonctions qui renvoient des valeurs sur des fonctions qui modifient des valeurs, car avec la première, la syntaxe d'assignation rend tout à fait clair ce qui est modifié. – unutbu