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))?
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.
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:]
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]
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))
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)
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!
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. )
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