web-dev-qa-db-fra.com

Pandas: divisez dataframe en plusieurs dataframes par nombre de lignes

assez nouveau pour les pandas, alors supporte-moi ...

J'ai un énorme CSV avec beaucoup de tables avec beaucoup de lignes. Je voudrais simplement scinder chaque image de données en 2 si elle contient plus de 10 lignes. 

Si cela est vrai, j'aimerais que le premier cadre de données contienne les 10 premiers et le reste dans le deuxième cadre de données. 

Y a-t-il une fonction pratique pour cela? J'ai regardé autour de moi mais je n'ai rien trouvé d'utile ... 

i.e. split_dataframe (df, 2 (si> 10))? 

21
Boosted_d16

Cela renverra les DataFrames scindés si la condition est remplie, sinon renverra l'original et None (que vous auriez alors besoin de gérer séparément). Notez que cela suppose que la division ne doit avoir lieu qu'une fois par df et que la deuxième partie de la division (si elle est supérieure à 10 lignes (ce qui signifie que l'original était supérieur à 20 lignes)) est OK.

df_new1, df_new2 = df[:10, :], df[10:, :] if len(df) > 10 else df, None

Notez que vous pouvez également utiliser df.head(10) et df.tail(len(df) - 10) pour obtenir le recto et le verso en fonction de vos besoins. Vous pouvez également utiliser différentes approches d’indexation: vous pouvez simplement fournir le premier index de dimensions, tel que df[:10] au lieu de df[:10, :] (bien que j’aimerais coder explicitement sur les dimensions que vous prenez). Vous pouvez également utiliser df.iloc et df.ix pour indexer de manière similaire.

Attention cependant à utiliser df.loc, car il est basé sur une étiquette et l'entrée ne sera jamais interprétée comme une position entière . .loc ne fonctionnerait que "accidentellement" dans le cas où vous auriez des étiquettes d'index entières commençant à 0 sans espace.

Cependant, vous devez également prendre en compte les différentes options offertes par les pandas pour transférer le contenu du DataFrame en HTML et éventuellement également LaTeX pour créer des tableaux mieux conçus pour la présentation (au lieu de simplement copier et coller). Il suffit de chercher dans Google pour convertir le DataFrame dans ces formats, ce qui génère de nombreux tutoriels et conseils pour exactement cette application.

15
ely

Il n'y a pas de fonction de confort spécifique.

Vous devez faire quelque chose comme:

first_ten = pd.DataFrame()
rest = pd.DataFrame()

if df.shape[0] > 10: # len(df) > 10 would also work
    first_ten = df[:10]
    rest = df[10:]
12
EdChum

Ci-dessous, une implémentation de fonction simple qui divise un DataFrame en morceaux et quelques exemples de code:

import pandas as pd

def split_dataframe_to_chunks(df, n):
    df_len = len(df)
    count = 0
    dfs = []

    while True:
        if count > df_len-1:
            break

        start = count
        count += n
        #print("%s : %s" % (start, count))
        dfs.append(df.iloc[start : count])
    return dfs


# Create a DataFrame with 10 rows
df = pd.DataFrame([i for i in range(10)])

# Split the DataFrame to chunks of maximum size 2
split_df_to_chunks_of_2 = split_dataframe_to_chunks(df, 2)
print([len(i) for i in split_df_to_chunks_of_2])
# prints: [2, 2, 2, 2, 2]

# Split the DataFrame to chunks of maximum size 3
split_df_to_chunks_of_3 = split_dataframe_to_chunks(df, 3)
print([len(i) for i in split_df_to_chunks_of_3])
# prints [3, 3, 3, 1]
1
Roei Bahumi

J'ai utilisé cette List Comprehensions pour couper un énorme df en blocs de 100 000:

size = 100000
list_of_dfs = [df.loc[i:i+size-1,:] for i in range(0, len(df),size)]

ou en tant que générateur:

list_of_dfs = (df.loc[i:i+size-1,:] for i in range(0, len(df),size))
1
agittarius

Vous pouvez utiliser les méthodes DataFrame head et tail en tant que sucre syntaxique au lieu de slicing/loc ici. J'utilise une taille de 3; pour votre exemple, utilisez headSize = 10

def split(df, headSize) :
    hd = df.head(headSize)
    tl = df.tail(len(df)-headSize)
    return hd, tl

df = pd.DataFrame({    'A':[2,4,6,8,10,2,4,6,8,10],
                       'B':[10,-10,0,20,-10,10,-10,0,20,-10],
                       'C':[4,12,8,0,0,4,12,8,0,0],
                      'D':[9,10,0,1,3,np.nan,np.nan,np.nan,np.nan,np.nan]})

# Split dataframe into top 3 rows (first) and the rest (second)
first, second = split(df, 3)
1
Tom Walker

Si vous avez un grand cadre de données et devez diviser en un nombre variable de lignes de sous-cadres de données, comme par exemple chaque sous-cadre de données a un maximum de 4500 lignes, ce script peut vous aider:

max_rows = 4500
dataframes = []
while len(df) > max_rows:
    top = df[:max_rows]
    dataframes.append(top)
    df = df[max_rows:]
else:
    dataframes.append(df)

Vous pouvez ensuite sauvegarder ces trames de données:

for _, frame in enumerate(dataframes):
    frame.to_csv(str(_)+'.csv', index=False)

J'espère que cela aide quelqu'un!

0
cheevahagadog

Une méthode basée sur np.split:

df = pd.DataFrame({    'A':[2,4,6,8,10,2,4,6,8,10],
                       'B':[10,-10,0,20,-10,10,-10,0,20,-10],
                       'C':[4,12,8,0,0,4,12,8,0,0],
                      'D':[9,10,0,1,3,np.nan,np.nan,np.nan,np.nan,np.nan]})

listOfDfs = [df.loc[idx] for idx in np.split(df.index,5)]

Une petite fonction qui utilise un modulo pourrait s’occuper des cas où la division n’est pas uniforme (par exemple, np.split(df.index,4) génère une erreur).

( Oui, je suis conscient que la question initiale était un peu plus spécifique que cela. Cependant, cela est censé répondre à la question dans le titre. )

0
webelo

La méthode basée sur la compréhension de liste et sur groupby, qui stocke toutes les images de données fractionnées dans une variable de liste et est accessible à l'aide de l'index.

Exemple:

ans = [pd.DataFrame(y) for x, y in DF.groupby('column_name', as_index=False)]***
ans[0]
ans[0].column_name
0
Ram Prajapati