Comment faire de bons exemples de pandas reproductibles

221

Après avoir passé un temps décent à regarder à la fois et balises sur SO, l'impression que j'ai, c'est que les pandasquestions sont moins susceptibles de contenir des données reproductibles. C'est quelque chose que la communauté R a été assez bonne pour encourager, et grâce à des guides comme celui-ci , les nouveaux arrivants peuvent obtenir de l'aide pour rassembler ces exemples. Les personnes capables de lire ces guides et de revenir avec des données reproductibles auront souvent beaucoup plus de chance d'obtenir des réponses à leurs questions.

Comment créer de bons exemples reproductibles de pandasquestions? Des trames de données simples peuvent être assemblées, par exemple:

import pandas as pd
df = pd.DataFrame({'user': ['Bob', 'Jane', 'Alice'], 
                   'income': [40000, 50000, 42000]})

Mais de nombreux exemples de jeux de données nécessitent une structure plus complexe, par exemple:

  • datetime indices ou données
  • Plusieurs variables catégorielles (existe-t-il un équivalent à la expand.grid()fonction de R , qui produit toutes les combinaisons possibles de certaines variables données?)
  • Données MultiIndex ou Panel

Pour les jeux de données difficiles à simuler à l'aide de quelques lignes de code, existe-t-il un équivalent aux R dput()qui vous permet de générer du code collable pour régénérer votre infrastructure de données?

Marius
la source
8
Si vous copiez la sortie de l'impression, la plupart du temps les répondeurs peuvent utiliser read_clipboard () ... sauf pour MultiIndex: s. Cela dit, dict est un bon ajout
Andy Hayden
8
En plus de ce que Andy a dit, je pense que copier-coller df.head(N).to_dict(), où Nest un nombre raisonnable est une bonne façon de procéder. Bonus + 1 pour l'ajout de jolis sauts de ligne à la sortie. Pour les horodatages, vous aurez généralement juste besoin d'ajouter from pandas import Timestampen haut du code.
Paul H

Réponses:

323

Remarque: Les idées ici sont assez génériques pour Stack Overflow, en effet des questions .

Avertissement: écrire une bonne question est DIFFICILE.

Le bon:

  • inclure un petit * exemple DataFrame, soit sous forme de code exécutable:

    In [1]: df = pd.DataFrame([[1, 2], [1, 3], [4, 6]], columns=['A', 'B'])

    ou le rendre "copiable et collable" en utilisant pd.read_clipboard(sep='\s\s+'), vous pouvez formater le texte pour mettre en surbrillance Stack Overflow et utiliser Ctrl+ K(ou ajouter quatre espaces à chaque ligne), ou placer trois tildes au-dessus et en dessous de votre code avec votre code sans indentation:

    In [2]: df
    Out[2]: 
       A  B
    0  1  2
    1  1  3
    2  4  6
    

    testez- pd.read_clipboard(sep='\s\s+')vous.

    * Je veux vraiment dire petit , la grande majorité des exemples de DataFrames pourraient être moins de 6 lignes de citation nécessaires , et je parie que je peux le faire en 5 lignes. Pouvez-vous reproduire l'erreur avec df = df.head(), sinon tripoter pour voir si vous pouvez composer un petit DataFrame qui présente le problème auquel vous êtes confronté.

    * Chaque règle a une exception, la plus évidente est des problèmes de performance ( dans ce cas , certainement utiliser% timeit et peut - être% Prun ), où vous devez générer (envisager d' utiliser np.random.seed nous avons donc le cadre exactement le même): df = pd.DataFrame(np.random.randn(100000000, 10)). Dire que "faire ce code rapidement pour moi" n'est pas strictement un sujet pour le site ...

  • écrivez le résultat que vous désirez (comme ci-dessus)

    In [3]: iwantthis
    Out[3]: 
       A  B
    0  1  5
    1  4  6
    

    Expliquez la provenance des nombres: le 5 est la somme de la colonne B pour les lignes où A est 1.

  • montrez le code que vous avez essayé:

    In [4]: df.groupby('A').sum()
    Out[4]: 
       B
    A   
    1  5
    4  6
    

    Mais dites ce qui est incorrect: la colonne A est dans l'index plutôt que dans une colonne.

  • montrez que vous avez fait des recherches ( recherchez dans les documents , recherchez StackOverflow ), donnez un résumé:

    La docstring pour sum indique simplement "Calculer la somme des valeurs de groupe"

    Les documents groupby ne donnent aucun exemple à ce sujet.

    À part: la réponse ici est d'utiliser df.groupby('A', as_index=False).sum().

  • s'il est pertinent que vous ayez des colonnes d'horodatage, par exemple que vous rééchantillonnez ou quelque chose, soyez explicite et appliquez- pd.to_datetimeleur pour faire bonne mesure **.

    df['date'] = pd.to_datetime(df['date']) # this column ought to be date..

    ** Parfois, c'est le problème lui-même: c'était des cordes.

Le mauvais:

  • ne pas inclure un MultiIndex, que nous ne pouvons pas copier-coller (voir ci-dessus), c'est une sorte de grief avec l'affichage par défaut des pandas mais néanmoins ennuyeux:

    In [11]: df
    Out[11]:
         C
    A B   
    1 2  3
      2  6
    

    La bonne façon est d'inclure un DataFrame ordinaire avec un set_indexappel:

    In [12]: df = pd.DataFrame([[1, 2, 3], [1, 2, 6]], columns=['A', 'B', 'C']).set_index(['A', 'B'])
    
    In [13]: df
    Out[13]: 
         C
    A B   
    1 2  3
      2  6
    
  • donnez un aperçu de ce que c'est lorsque vous donnez le résultat souhaité:

       B
    A   
    1  1
    5  0
    

    Soyez précis sur la façon dont vous avez obtenu les chiffres (quels sont-ils) ... vérifiez bien qu'ils sont corrects.

  • Si votre code génère une erreur, incluez la trace de pile entière (cela peut être édité plus tard s'il est trop bruyant). Montrez le numéro de ligne (et la ligne correspondante de votre code contre laquelle il s'élève).

Le moche:

  • ne pas lier à un csv auquel nous n'avons pas accès (idéalement ne pas lier à une source externe du tout ...)

    df = pd.read_csv('my_secret_file.csv')  # ideally with lots of parsing options

    La plupart des données sont propriétaires, nous obtenons cela: Créez des données similaires et voyez si vous pouvez reproduire le problème (quelque chose de petit).

  • n'expliquez pas vaguement la situation avec des mots, comme vous avez un DataFrame qui est "grand", mentionnez quelques noms de colonnes en passant (assurez-vous de ne pas mentionner leurs dtypes). Essayez d'entrer dans beaucoup de détails sur quelque chose qui n'a aucun sens sans voir le contexte réel. Vraisemblablement, personne ne va même lire jusqu'à la fin de ce paragraphe.

    Les essais sont mauvais, c'est plus facile avec de petits exemples.

  • n'incluez pas 10+ (100+ ??) lignes de transfert de données avant d'arriver à votre question réelle.

    S'il vous plaît, nous en voyons suffisamment dans nos emplois de jour. Nous voulons aider, mais pas comme ça ... .
    Coupez l'intro et montrez simplement les DataFrames pertinents (ou leurs petites versions) à l'étape qui vous pose problème.

Quoi qu'il en soit, amusez-vous à apprendre Python, NumPy et Pandas!

Andy Hayden
la source
30
+1 pour la pd.read_clipboard(sep='\s\s+')pointe. Lorsque je poste des questions SO qui nécessitent une trame de données spéciale mais facilement partagée, comme celle-ci, je la construis dans Excel, la copie dans mon presse-papiers, puis demande aux SOers de faire de même. Économise tellement de temps!
zelusp
1
la pd.read_clipboard(sep='\s\s+')suggestion ne semble pas fonctionner si vous utilisez Python sur un serveur distant, où vivent de nombreux ensembles de données volumineux.
user5359531
1
Pourquoi pd.read_clipboard(sep='\s\s+'), et pas plus simple pd.read_clipboard()(avec la valeur par défaut ‘s+’)? Le premier besoin d' au moins 2 caractères blancs, ce qui peut causer des problèmes s'il y a seulement 1 (par exemple , voir par exemple dans le de » @JohnE la réponse ).
MarianD
3
@MarianD la raison pour laquelle \ s \ s + est si populaire est qu'il y en a souvent un par exemple dans un nom de colonne, mais le multiple est plus rare, et la sortie pandas en met bien au moins deux entre les colonnes. Puisque c'est juste pour les jouets / petits ensembles de données, c'est assez puissant / la majorité des cas. Remarque: les tabulations séparées seraient une histoire différente, bien que stackoverflow remplace les tabulations par des espaces, mais si vous avez un tsv, utilisez simplement \ t.
Andy Hayden
3
Ugh, j'utilise toujours pd.read_clipboard(), quand ce sont des espaces, je fais pd.read_clipboard(sep='\s+{2,}', engine='python'):: P
U10-Forward
72

Comment créer des exemples de jeux de données

Il s'agit principalement d'étendre la réponse de @ AndyHayden en fournissant des exemples de la façon dont vous pouvez créer des exemples de trames de données. Les pandas et (en particulier) numpy vous offrent une variété d'outils pour cela, de sorte que vous pouvez généralement créer un fac-similé raisonnable de tout ensemble de données réel avec seulement quelques lignes de code.

Après avoir importé numpy et pandas, assurez-vous de fournir une graine aléatoire si vous voulez que les gens puissent reproduire exactement vos données et résultats.

import numpy as np
import pandas as pd

np.random.seed(123)

Un exemple d'évier de cuisine

Voici un exemple montrant une variété de choses que vous pouvez faire. Toutes sortes d'exemples de trames de données utiles pourraient être créées à partir d'un sous-ensemble de ceci:

df = pd.DataFrame({ 

    # some ways to create random data
    'a':np.random.randn(6),
    'b':np.random.choice( [5,7,np.nan], 6),
    'c':np.random.choice( ['panda','python','shark'], 6),

    # some ways to create systematic groups for indexing or groupby
    # this is similar to r's expand.grid(), see note 2 below
    'd':np.repeat( range(3), 2 ),
    'e':np.tile(   range(2), 3 ),

    # a date range and set of random dates
    'f':pd.date_range('1/1/2011', periods=6, freq='D'),
    'g':np.random.choice( pd.date_range('1/1/2011', periods=365, 
                          freq='D'), 6, replace=False) 
    })

Cela produit:

          a   b       c  d  e          f          g
0 -1.085631 NaN   panda  0  0 2011-01-01 2011-08-12
1  0.997345   7   shark  0  1 2011-01-02 2011-11-10
2  0.282978   5   panda  1  0 2011-01-03 2011-10-30
3 -1.506295   7  python  1  1 2011-01-04 2011-09-07
4 -0.578600 NaN   shark  2  0 2011-01-05 2011-02-27
5  1.651437   7  python  2  1 2011-01-06 2011-02-03

Quelques notes:

  1. np.repeatet np.tile(colonnes det e) sont très utiles pour créer des groupes et des indices de manière très régulière. Pour 2 colonnes, cela peut être utilisé pour dupliquer facilement les r expand.grid()mais est également plus flexible dans la capacité à fournir un sous-ensemble de toutes les permutations. Cependant, pour 3 colonnes ou plus, la syntaxe devient rapidement compliquée.
  2. Pour un remplacement plus direct des r, expand.grid()voir la itertoolssolution dans le livre de recettes pandas ou la np.meshgridsolution présentée ici . Ceux-ci permettront un nombre illimité de dimensions.
  3. Vous pouvez en faire pas mal avec np.random.choice. Par exemple, dans la colonne g, nous avons une sélection aléatoire de 6 dates à partir de 2011. De plus, en définissant, replace=Falsenous pouvons garantir que ces dates sont uniques - très pratique si nous voulons l'utiliser comme un index avec des valeurs uniques.

Fausse donnée boursière

En plus de prendre des sous-ensembles du code ci-dessus, vous pouvez combiner davantage les techniques pour faire à peu près n'importe quoi. Par exemple, voici un court exemple qui combine np.tileet date_rangecrée des exemples de données de ticker pour 4 actions couvrant les mêmes dates:

stocks = pd.DataFrame({ 
    'ticker':np.repeat( ['aapl','goog','yhoo','msft'], 25 ),
    'date':np.tile( pd.date_range('1/1/2011', periods=25, freq='D'), 4 ),
    'price':(np.random.randn(100).cumsum() + 10) })

Nous avons maintenant un exemple de jeu de données avec 100 lignes (25 dates par ticker), mais nous n'avons utilisé que 4 lignes pour le faire, ce qui permet à tout le monde de reproduire facilement sans copier ni coller 100 lignes de code. Vous pouvez ensuite afficher des sous-ensembles de données si cela aide à expliquer votre question:

>>> stocks.head(5)

        date      price ticker
0 2011-01-01   9.497412   aapl
1 2011-01-02  10.261908   aapl
2 2011-01-03   9.438538   aapl
3 2011-01-04   9.515958   aapl
4 2011-01-05   7.554070   aapl

>>> stocks.groupby('ticker').head(2)

         date      price ticker
0  2011-01-01   9.497412   aapl
1  2011-01-02  10.261908   aapl
25 2011-01-01   8.277772   goog
26 2011-01-02   7.714916   goog
50 2011-01-01   5.613023   yhoo
51 2011-01-02   6.397686   yhoo
75 2011-01-01  11.736584   msft
76 2011-01-02  11.944519   msft
JohnE
la source
2
Très bonne réponse. Après avoir écrit cette question, j'ai en fait écrit une implémentation très courte et simple expand.grid()qui est incluse dans le livre de cuisine pandas , vous pouvez également l'inclure dans votre réponse. Votre réponse montre comment créer des ensembles de données plus complexes que ce que ma expand_grid()fonction pourrait gérer, ce qui est formidable.
Marius
46

Journal d'un répondeur

Mon meilleur conseil pour poser des questions serait de jouer sur la psychologie des personnes qui répondent aux questions. Étant une de ces personnes, je peux expliquer pourquoi je réponds à certaines questions et pourquoi je ne réponds pas à d'autres.

Les motivations

Je suis motivé pour répondre aux questions pour plusieurs raisons

  1. Stackoverflow.com a été une ressource extrêmement précieuse pour moi. Je voulais redonner.
  2. Dans mes efforts pour redonner, j'ai trouvé que ce site était une ressource encore plus puissante qu'auparavant. Répondre aux questions est une expérience d'apprentissage pour moi et j'aime apprendre. Lisez cette réponse et commentez un autre vétérinaire . Ce genre d'interaction me fait plaisir.
  3. J'aime les points!
  4. Voir # 3.
  5. J'aime les problèmes intéressants.

Toutes mes intentions les plus pures sont grandes et toutes, mais j'obtiens cette satisfaction si je réponds à 1 question ou 30. Ce qui motive mes choix pour les questions auxquelles répondre a une énorme composante de maximisation des points.

Je vais également passer du temps sur des problèmes intéressants, mais cela est rare et n'aide pas un demandeur qui a besoin d'une solution à une question non intéressante. Votre meilleur pari pour me faire répondre à une question est de servir cette question sur un plateau mûr pour que je puisse y répondre avec le moins d'effort possible. Si je regarde deux questions et que l'une a du code, je peux copier-coller pour créer toutes les variables dont j'ai besoin ... Je prends celle-là! Je reviendrai sur l'autre si j'ai le temps, peut-être.

Conseil principal

Facilitez la tâche aux personnes qui répondent aux questions.

  • Fournissez du code qui crée les variables nécessaires.
  • Réduisez ce code. Si mes yeux brillent lorsque je regarde le post, je passe à la question suivante ou je reviens à tout ce que je fais.
  • Pensez à ce que vous demandez et soyez précis. Nous voulons voir ce que vous avez fait car les langues naturelles (anglais) sont inexactes et déroutantes. Des exemples de code de ce que vous avez essayé aident à résoudre les incohérences dans une description en langage naturel.
  • VEUILLEZ montrer ce que vous attendez !!! Je dois m'asseoir et essayer des choses. Je ne connais presque jamais la réponse à une question sans essayer certaines choses. Si je ne vois pas d'exemple de ce que vous cherchez, je pourrais passer la question parce que je n'ai pas envie de deviner.

Votre réputation est plus que votre réputation.

J'aime les points (je l'ai mentionné ci-dessus). Mais ces points ne sont pas vraiment ma réputation. Ma vraie réputation est un amalgame de ce que les autres sur le site pensent de moi. Je m'efforce d'être juste et honnête et j'espère que les autres pourront le voir. Ce que cela signifie pour un demandeur, nous nous souvenons des comportements des demandeurs. Si vous ne sélectionnez pas de réponses et votez pour de bonnes réponses, je m'en souviens. Si vous vous comportez d'une manière que je n'aime pas ou d'une manière que j'aime, je m'en souviens. Cela joue également dans les questions auxquelles je répondrai.


Quoi qu'il en soit, je peux probablement continuer, mais je vous épargnerai tous ceux qui ont lu ceci.

piRSquared
la source
26

Le défi L'un des aspects les plus difficiles de la réponse aux questions de SO est le temps nécessaire pour recréer le problème (y compris les données). Les questions qui n'ont pas de moyen clair de reproduire les données ont moins de chances de trouver une réponse. Étant donné que vous prenez le temps d'écrire une question et que vous souhaitez résoudre un problème, vous pouvez facilement vous aider en fournissant des données que d'autres pourront ensuite utiliser pour vous aider à résoudre votre problème.

Les instructions fournies par @Andy pour écrire de bonnes questions Pandas sont un excellent point de départ. Pour plus d'informations, reportez-vous à la façon de demander et comment créer des exemples Minimal, Complete et Verifiable .

Veuillez énoncer clairement votre question dès le départ. Après avoir pris le temps d'écrire votre question et tout exemple de code, essayez de le lire et de fournir un «résumé» à votre lecteur qui résume le problème et énonce clairement la question.

Question d'origine :

J'ai ces données ...

Je veux faire ça...

Je veux que mon résultat ressemble à ceci ...

Cependant, quand j'essaye de faire [ceci], j'obtiens le problème suivant ...

J'ai essayé de trouver des solutions en faisant [ceci] et [cela].

Comment je le répare?

En fonction de la quantité de données, des exemples de code et des piles d'erreurs fournis, le lecteur doit parcourir un long chemin avant de comprendre le problème. Essayez de reformuler votre question afin que la question elle-même soit en haut, puis fournissez les détails nécessaires.

Question révisée :

Qustion: Comment puis-je faire [ceci]?

J'ai essayé de trouver des solutions en faisant [ceci] et [cela].

Quand j'ai essayé de faire [ceci], j'ai le problème suivant ...

J'aimerais que mes résultats finaux ressemblent à ça ...

Voici un code minimal qui peut reproduire mon problème ...

Et voici comment recréer mes exemples de données: df = pd.DataFrame({'A': [...], 'B': [...], ...})

FOURNIR DES EXEMPLES DE DONNÉES SI NÉCESSAIRE !!!

Parfois, seule la tête ou la queue du DataFrame suffit. Vous pouvez également utiliser les méthodes proposées par @JohnE pour créer de plus grands ensembles de données qui peuvent être reproduits par d'autres. En utilisant son exemple pour générer un DataFrame de 100 lignes de cours des actions:

stocks = pd.DataFrame({ 
    'ticker':np.repeat( ['aapl','goog','yhoo','msft'], 25 ),
    'date':np.tile( pd.date_range('1/1/2011', periods=25, freq='D'), 4 ),
    'price':(np.random.randn(100).cumsum() + 10) })

S'il s'agissait de vos données réelles, vous souhaiterez peut-être simplement inclure la tête et / ou la queue de la trame de données comme suit (veillez à anonymiser toutes les données sensibles):

>>> stocks.head(5).to_dict()
{'date': {0: Timestamp('2011-01-01 00:00:00'),
  1: Timestamp('2011-01-01 00:00:00'),
  2: Timestamp('2011-01-01 00:00:00'),
  3: Timestamp('2011-01-01 00:00:00'),
  4: Timestamp('2011-01-02 00:00:00')},
 'price': {0: 10.284260107718254,
  1: 11.930300761831457,
  2: 10.93741046217319,
  3: 10.884574289565609,
  4: 11.78005850418319},
 'ticker': {0: 'aapl', 1: 'aapl', 2: 'aapl', 3: 'aapl', 4: 'aapl'}}

>>> pd.concat([stocks.head(), stocks.tail()], ignore_index=True).to_dict()
{'date': {0: Timestamp('2011-01-01 00:00:00'),
  1: Timestamp('2011-01-01 00:00:00'),
  2: Timestamp('2011-01-01 00:00:00'),
  3: Timestamp('2011-01-01 00:00:00'),
  4: Timestamp('2011-01-02 00:00:00'),
  5: Timestamp('2011-01-24 00:00:00'),
  6: Timestamp('2011-01-25 00:00:00'),
  7: Timestamp('2011-01-25 00:00:00'),
  8: Timestamp('2011-01-25 00:00:00'),
  9: Timestamp('2011-01-25 00:00:00')},
 'price': {0: 10.284260107718254,
  1: 11.930300761831457,
  2: 10.93741046217319,
  3: 10.884574289565609,
  4: 11.78005850418319,
  5: 10.017209045035006,
  6: 10.57090128181566,
  7: 11.442792747870204,
  8: 11.592953372130493,
  9: 12.864146419530938},
 'ticker': {0: 'aapl',
  1: 'aapl',
  2: 'aapl',
  3: 'aapl',
  4: 'aapl',
  5: 'msft',
  6: 'msft',
  7: 'msft',
  8: 'msft',
  9: 'msft'}}

Vous pouvez également vouloir fournir une description du DataFrame (en utilisant uniquement les colonnes pertinentes). Cela permet aux autres de vérifier plus facilement les types de données de chaque colonne et d'identifier d'autres erreurs courantes (par exemple, les dates sous forme de chaîne par rapport à datetime64 par rapport à l'objet):

stocks.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 100 entries, 0 to 99
Data columns (total 3 columns):
date      100 non-null datetime64[ns]
price     100 non-null float64
ticker    100 non-null object
dtypes: datetime64[ns](1), float64(1), object(1)

REMARQUE: si votre DataFrame a un MultiIndex:

Si votre DataFrame a un multiindex, vous devez d'abord réinitialiser avant d'appeler to_dict. Vous devez ensuite recréer l'index en utilisant set_index:

# MultiIndex example.  First create a MultiIndex DataFrame.
df = stocks.set_index(['date', 'ticker'])
>>> df
                       price
date       ticker           
2011-01-01 aapl    10.284260
           aapl    11.930301
           aapl    10.937410
           aapl    10.884574
2011-01-02 aapl    11.780059
...

# After resetting the index and passing the DataFrame to `to_dict`, make sure to use 
# `set_index` to restore the original MultiIndex.  This DataFrame can then be restored.

d = df.reset_index().to_dict()
df_new = pd.DataFrame(d).set_index(['date', 'ticker'])
>>> df_new.head()
                       price
date       ticker           
2011-01-01 aapl    10.284260
           aapl    11.930301
           aapl    10.937410
           aapl    10.884574
2011-01-02 aapl    11.780059
Alexandre
la source
12

Voici ma version de dput- l'outil R standard pour produire des rapports reproductibles - pour Pandas DataFrames. Il échouera probablement pour des trames plus complexes, mais il semble faire l'affaire dans des cas simples:

import pandas as pd
def dput (x):
    if isinstance(x,pd.Series):
        return "pd.Series(%s,dtype='%s',index=pd.%s)" % (list(x),x.dtype,x.index)
    if isinstance(x,pd.DataFrame):
        return "pd.DataFrame({" + ", ".join([
            "'%s': %s" % (c,dput(x[c])) for c in x.columns]) + (
                "}, index=pd.%s)" % (x.index))
    raise NotImplementedError("dput",type(x),x)

maintenant,

df = pd.DataFrame({'a':[1,2,3,4,2,1,3,1]})
assert df.equals(eval(dput(df)))
du = pd.get_dummies(df.a,"foo")
assert du.equals(eval(dput(du)))
di = df
di.index = list('abcdefgh')
assert di.equals(eval(dput(di)))

Notez que cela produit une sortie beaucoup plus détaillée que DataFrame.to_dict, par exemple,

pd.DataFrame({
  'foo_1':pd.Series([1, 0, 0, 0, 0, 1, 0, 1],dtype='uint8',index=pd.RangeIndex(start=0, stop=8, step=1)),
  'foo_2':pd.Series([0, 1, 0, 0, 1, 0, 0, 0],dtype='uint8',index=pd.RangeIndex(start=0, stop=8, step=1)),
  'foo_3':pd.Series([0, 0, 1, 0, 0, 0, 1, 0],dtype='uint8',index=pd.RangeIndex(start=0, stop=8, step=1)),
  'foo_4':pd.Series([0, 0, 0, 1, 0, 0, 0, 0],dtype='uint8',index=pd.RangeIndex(start=0, stop=8, step=1))},
  index=pd.RangeIndex(start=0, stop=8, step=1))

contre

{'foo_1': {0: 1, 1: 0, 2: 0, 3: 0, 4: 0, 5: 1, 6: 0, 7: 1}, 
 'foo_2': {0: 0, 1: 1, 2: 0, 3: 0, 4: 1, 5: 0, 6: 0, 7: 0}, 
 'foo_3': {0: 0, 1: 0, 2: 1, 3: 0, 4: 0, 5: 0, 6: 1, 7: 0}, 
 'foo_4': {0: 0, 1: 0, 2: 0, 3: 1, 4: 0, 5: 0, 6: 0, 7: 0}}

pour duci-dessus, mais il conserve les types de colonnes . Par exemple, dans le cas de test ci-dessus,

du.equals(pd.DataFrame(du.to_dict()))
==> False

car du.dtypesest uint8et pd.DataFrame(du.to_dict()).dtypesest int64.

sds
la source
c'est plus clair, bien que j'avoue que je ne vois pas pourquoi je voudrais l'utiliser dessusto_dict
Paul H
2
Parce qu'il préserve les types de colonnes. Plus précisément, du.equals(eval(dput(df))).
sds