2
votes

Est-il possible d'ajouter des listes de différentes longueurs sous forme de colonnes dans un dataframe vide?

J'essaie de créer un code qui prend un ensemble de lettres et génère le nombre différent de mots que vous pouvez créer avec eux.

Voici mon code pour l'instant:

ValueError: cannot set a row with mismatched columns

En ignorant la dernière ligne de code, cela fonctionne très bien.

Avec ce code, j'obtiens l'erreur:

ValueError: cannot set a frame with no defined column

J'ai donc ajouté des colonnes en changeant mon dframe en dframe = pd.dataframe (columns = list (range (2, n + 1,1)))

J'ai alors eu l'erreur suivante:

import itertools as itr
import requests
from PyDictionary import PyDictionary
import pandas as pd

x=list(input("enter letters given:"))
n=len(x)
dframe=pd.DataFrame()
dictionary=PyDictionary()
for i in range(2,n+1,1):
    combinations=list(itr.combinations_with_replacement(x,i))
    format_combinations=[]
    for letters in combinations:
        format_combinations.append(' '.join(letters))

    for idx,word in enumerate(format_combinations):
        word=word.replace(" ","")
        format_combinations[idx]=word
    dframe.loc[i]=format_combinations


0 commentaires

3 Réponses :


1
votes

.loc [] et .iloc [] ne vous permettront pas de créer une nouvelle colonne.
Utilisez des crochets simples pour créer une colonne:

import itertools as itr
import requests
from PyDictionary import PyDictionary
import pandas as pd
x=list(input("enter letters given:"))
n=len(x)
results={}
dictionary=PyDictionary()
for i in range(2,n+1,1):
    combinations=list(itr.combinations_with_replacement(x,i))
    format_combinations=[]
    for letters in combinations:
        format_combinations.append(' '.join(letters))
    for idx,word in enumerate(format_combinations):
        word=word.replace(" ","")
        format_combinations[idx]=word
    results[i]=format_combinations
for res in results:
    print(results[res],'\n')

Cependant, vous aurez alors le problème de créer des colonnes avec des longueurs différentes de celles de l'index. Vous devrez soit remplir chaque colonne avec NAs (NaNs), soit je suggérerais, au lieu d'utiliser un DataFrame, d'utiliser un dictionnaire python, où la CLE est votre 'i' et la VALUE est votre liste de format_combinations. Vous pouvez ensuite parcourir le dictionnaire de la même manière que vous le feriez dans les colonnes du dataframe. Alternativement, puisque vous tapez essentiellement par nombre entier, au lieu d'un dictionnaire, créez simplement une liste de listes, où l'élément de liste 'i' pointe vers la liste 'format_combinations'

Voici votre code utilisant un dictionnaire, ceci fonctionne (bien que je ne vérifie pas encore la validité du mot dans le dictionnaire)

dframe[i]=format_combinations

Ma compréhension d'un DataFrame est que les colonnes doivent toutes être de la même longueur que l'index --- c'est possible d'avoir des données éparses, ou des colonnes de longueurs `` effectivement '' différentes, mais (si je comprends bien) uniquement en remplissant les valeurs manquantes avec NaN (ou une autre valeur pour représenter une valeur manquante, telle qu'une chaîne nulle ou vide).


0 commentaires

1
votes

Vous devez d'abord attribuer un nom aux colonnes du dataframe:

dframe = pd.DataFrame(columns=['Combinations'])
...
dframe.loc[i, 'Combinations'] = format_combinations


1 commentaires

Agréable! Cela fonctionne aussi! Cela crée un DataFrame avec une colonne unique où chaque ligne est la liste des 'format_combinations' correspondant à 'i' ... essentiellement la colonne unique est le dict que j'ai mentionné dans ma réponse.



1
votes

Je ne suis pas sûr que ce soit la solution exacte que vous recherchiez, mais lorsque je crée un dataframe pandas par itération, j'aime utiliser un tableau numpy comme intermédiaire. Ce que vous pouvez faire est:

  1. ajouter chaque itération à une liste python
  2. convertir cette liste en un tableau numpy et des valeurs de remplissage (j'ai utilisé des NaN pour remplir)
  3. convertir votre tableau numpy en dataframe
import itertools as itr
import requests
import pandas as pd
x=list(input("enter letters given:"))
n=len(x)
# initialize empty dataframe
all_combs = pd.DataFrame()
for i in range(2,n+1,1):
       combinations=list(itr.combinations_with_replacement(x,i))
       format_combinations=[]
       for letters in combinations:
           format_combinations.append(' '.join(letters))
       for idx,word in enumerate(format_combinations):
           word=word.replace(" ","")
           format_combinations[idx]=word
       # create dataframe with one column named for this iteration
       df = pd.DataFrame.from_dict({i: format_combinations})
       # join with all_combs on the union of their indices
       all_combs = all_combs.join(df, how='outer')

MODIFIER: Méthode alternative n'utilisant pas numpy

import itertools as itr
import requests
import pandas as pd
# import numpy
import numpy as np
x=list(input("enter letters given:"))
n=len(x)
# initialize a list
all_combs = []
for i in range(2,n+1,1):
       combinations=list(itr.combinations_with_replacement(x,i))
       format_combinations=[]
       for letters in combinations:
           format_combinations.append(' '.join(letters))
       for idx,word in enumerate(format_combinations):
           word=word.replace(" ","")
           format_combinations[idx]=word
       # append each iteration to the list
       all_combs.append(format_combinations)
# find the length of the longest iteration
pad = len(max(all_combs, key=len))
# create a numpy array from your list, pad with nans
arr = np.array([i + [np.nan]*(pad-len(i)) for i in all_combs])
# convert to dataframe
df = pd.DataFrame(arr)
# transpose to get one column per iteration
df = df.transpose()


2 commentaires

C'est ce que je cherchais, df a juste besoin d'être transposé comme fin.


Gotcha, a ajouté une méthode alternative pour obtenir une colonne par itération.