0
votes

convertir la liste en dataframe à l'aide du dictionnaire

Je suis nouveau sur Pythonland et j'ai une question. J'ai une liste comme ci-dessous et je souhaite la convertir en dataframe.

J'ai lu sur Stackoverflow qu'il vaut mieux créer un dictionnaire puis une liste donc j'en crée une comme suit.

column_names = ["name", "height" , "weight", "grade"] # Actual list has 10 entries

row_names = ["jack", "mick", "nick","pick"]

data = ['100','50','A','107','62','B'] # The actual list has 1640 entries

dic = {key:[] for key in column_names}
dic['name'] = row_names
t = 0
while t< len(data):
    dic['height'].append(data[t])
    t = t+3
t = 1
while t< len(data):
    dic['weight'].append(data[t])
    t = t+3


1 commentaires

il vous manque quelques guillemets dans vos exemples de noms de ligne / colonne. aussi, je pense que je comprends la déconnexion, en regardant comment vos données sont créées. La façon la plus probable de créer un dict est la façon dont les données sont dans des groupes logiques de colonnes , c'est généralement ainsi que nous devrions penser aux dataframes.


5 Réponses :


0
votes

Vous pouvez parcourir columnn_names comme ceci:

dic = {key:[] for key in column_names}
dic['name'] = row_names
for t, column_name in enumerate(column_names):
    i = t
    while i< len(data):
        dic[column_name].append(data[i])
        i += 3

Enumerate effectuera automatiquement une itération de t de 0 à len ( nom_colonne) -1


2 commentaires

merci pour la réponse rapide, mais le code ci-dessus énumérera également la clé «nom», donc la sortie souhaitée n'est pas obtenue.


Vous pouvez donc exclure cela de la liste sur laquelle vous répéterez. pour t, nom_colonne dans énumération (noms_colonne [1:]):



0
votes
i = 0
while True:
    try:
        for j in column_names:
            d[j].append(data[i])
            i += 1

    except Exception as er:  #So when i value exceed by data list it comes to exception and it will break the loop as well
        print(er, "################")
        break

0 commentaires

0
votes

Le premier problème est que toutes les données des colonnes sont concaténées dans une seule liste. Vous devriez d'abord étudier comment l'empêcher et avoir une liste de listes avec chaque valeur de colonne dans une liste séparée comme [['100', '107'], ['50', '62'], ['A' , 'B']] . De toute façon, vous avez besoin de cette structure de données pour procéder efficacement:

df = pd.DataFrame({j: spl_data[i] for i, j in enumerate(column_names)})

Ensuite, vous devez utiliser la compréhension de dict. Ceci est une fonctionnalité Python 3.x donc elle ne fonctionnera pas dans Py 2.x.

cl_count = len(column_names)
d_count = len(data)
spl_data = [[data[j] for j in range(i, d_count, cl_count)] for i in range(cl_count)] 


0 commentaires

0
votes

Tout d'abord, nous devons comprendre à quoi devrait ressembler un dictionnaire idéal pour un dataframe.

Un Dataframe peut être pensé de deux manières différentes:
La première est une collection de lignes traditionnelle ..

for i, val in enumerate(row): #just iterate through the row, keeping index too using enumerate
    dic[remaining_cols[i]].append(val) #use indexes to access the correct list in the dictionary

Cependant, il existe une deuxième représentation qui est plus utile, mais peut-être pas aussi intuitive au début .
Une collection de colonnes:

data_it = iter(data) #prepares an iterator. 

[data_it] * len(remaining_cols) #creates references to the same iterator

Maintenant, voici l'essentiel à réaliser, la 2ème représentation est plus utile car c'est la représentation prise en charge et utilisée en interne dans les dataframes.
Il ne rencontre pas de conflit de type de données au sein d'un seul groupement (chaque colonne doit avoir 1 type de données fixe) Cependant, dans une représentation de ligne, les types de données peuvent varier.
En outre, les opérations peuvent être effectuées facilement et de manière cohérente sur une colonne entière en raison de cette cohérence qui ne peut être garantie dans une ligne.

Ainsi, les tl; dr DataFrames sont essentiellement des collections de colonnes de même longueur.

Ainsi, un dictionnaire dans cette représentation peut être facilement converti en DataFrame.

import pd
df = pd.DataFrame(dic, columns = column_names)
print(df)
   name  height  weight grade
0  jack     100      50     A
1  mick     107      62     B

Donc, avec cela à l'esprit, la première chose à réaliser est que, dans leur format actuel, les données sont une très mauvaise représentation. C'est une collection de lignes fusionnées en une seule liste.

La première chose à faire, si vous êtes celui qui contrôle la façon dont les données sont formées, est de ne pas les préparer de cette façon.

Le but est une liste pour chaque colonne , et idéalement, préparez la liste dans ce format.

Maintenant, cependant, si elle est donnée dans ce format, vous devez itérer et collecter les valeurs en conséquence. Voici une façon de le faire

{'name': ['jack', 'mick'],
 'height': [100, 107],
 'weight': [50, 62],
 'grade': ['A', 'B']}

Sortie jusqu'à présent:

{'height': [],
 'weight': [],
 'grade': [],
 'name': ['jack', 'mick']} #so, now, names are a column representation with all correct values.

remaining_cols = column_names[1:]

#Explanations for the following part given at the end
data_it = iter(data)
for row in zip(*([data_it] * len(remaining_cols))):
    for i, val in enumerate(row):
        dic[remaining_cols[i]].append(val)

print(dic)

Sortie:

column_names = ["name", "height" , "weight", "grade"] # Actual list has 10 entries
row_names = ["jack", "mick"]
data = [100, 50,'A', 107, 62,'B'] # The actual list has 1640 entries

dic = {key:[] for key in column_names}
dic['name'] = row_names
print(dic)

Et nous en avons terminé avec la représentation

Enfin:

column_names = ["name", "height" , "weight", "grade"] # Actual list has 10 entries

row_names = ["jack", "mick"]

data = [100, 50,'A', 107, 62,'B'] # The actual list has 1640 entries

Edit: Quelques explications pour la partie zip: zip prend tous les itérables et nous permet de les parcourir ensemble.

'name': ['jack', 'mick'],
'height': ['100', '107'],
'weight': ['50', '62'],
'grade': ['A', 'B']

Ici, c'est similaire à [data_it, data_it, data_it ]

Le * dans * [data_it, data_it, data_it] nous permet de décompresser la liste en 3 arguments pour la fonction zip au lieu ainsi, f (* [data_it, data_it, data_it]) équivaut à f (data_it, data_it, data_it) pour toute fonction f.

la magie ici est que traverser un itérateur / faire avancer un itérateur reflètera désormais le changement dans toutes les références

En rassemblant tout cela: zip (* ([data_it] * len (restants_cols))) nous permettra en fait de prendre 3 éléments à partir de données à la fois, et de l'affecter à la ligne Donc, row = (100, 50, 'A') dans la première itération de zip

'row 0':  ['jack', 100, 50, 'A'],
'row 1':  ['mick', 107, 62, 'B']

J'espère que cela vous aidera.

p>


0 commentaires

0
votes

Si vous utilisez Python 3.x, comme suggéré par l159 , vous pouvez utiliser un dict de compréhension, puis créer un Pandas DataFrame hors de celui-ci, en utilisant les noms comme index de ligne:

     height weight grade
jack    100     50     A
mick    107     62     B
nick    103     64     C
pick    105     78     D

En fait, le dictionnaire intermédiaire est un dictionnaire imbriqué: les clés du dictionnaire externe sont les étiquettes de ligne (dans ce cas, les éléments de la liste row_names ); la valeur associée à chaque clé est un dictionnaire dont les clés sont les étiquettes de colonne (c'est-à-dire les éléments dans column_names ) et les valeurs sont les éléments correspondants dans la liste data . p>

La fonction from_dict est utilisé pour créer l'instance DataFrame.

Ainsi, le code précédent produit le résultat suivant:

data = ['100', '50', 'A', '107', '62', 'B', '103', '64', 'C', '105', '78', 'D']
column_names = ["height", "weight", "grade"]
row_names = ["jack", "mick", "nick", "pick"]

df = pd.DataFrame.from_dict(
    {
        row_label: {
            column_label: data[i * len(column_names) + j]
            for j, column_label in enumerate(column_names)
        } for i, row_label in enumerate(row_names)
    },
    orient='index'
)


0 commentaires