supposons un dataframe comme celui-ci:
df = pd.DataFrame([[1,2,3,4],[5,6,7,8],[9,10,11,12]], columns = ['A', 'B', 'A1', 'B1'])
Je voudrais avoir un cadre de données qui ressemble à:
ce qui ne marche pas:
new_rows = int(df.shape[1]/2) * df.shape[0]
new_cols = 2
df.values.reshape(new_rows, new_cols, order='F')
bien sûr, je pourrais parcourir les données et faire une nouvelle liste, mais il doit y avoir un meilleur moyen. Des idées ?
La fonction pd.wide_to_long
est construite presque exactement pour cette situation, où vous avez plusieurs préfixes de variable identiques se terminant par un suffixe numérique différent. La seule différence est que votre premier ensemble de variables n'a pas de suffixe, vous devez donc renommer vos colonnes en premier.
Le seul problème avec pd.wide_to_long
est qu'il doit avoir une variable d'identification, i
, contrairement à melt
. reset_index
est utilisé pour créer une colonne d'identification unique, qui sera supprimée ultérieurement. Je pense que cela pourrait être corrigé à l'avenir.
df1 = df.rename(columns={'A':'A1', 'B':'B1', 'A1':'A2', 'B1':'B2'}).reset_index()
pd.wide_to_long(df1, stubnames=['A', 'B'], i='index', j='id')\
.reset_index()[['A', 'B', 'id']]
A B id
0 1 2 1
1 5 6 1
2 9 10 1
3 3 4 2
4 7 8 2
5 11 12 2
Vous pouvez utiliser lreshape
, pour la colonne id
numpy.repeat
:
a = [col for col in df.columns if 'A' in col]
b = [col for col in df.columns if 'B' in col]
df1 = pd.lreshape(df, {'A' : a, 'B' : b})
df1['id'] = np.repeat(np.arange(len(df.columns) // 2), len (df.index)) + 1
print (df1)
A B id
0 1 2 1
1 5 6 1
2 9 10 1
3 3 4 2
4 7 8 2
5 11 12 2
MODIFIER:
lreshape
est actuellement non documenté, mais il est possible de le supprimer ( avec pd.wide_to_long aussi ).
La solution possible est de fusionner les 3 fonctions en une seule - peut-être melt
, mais maintenant, elle n'est pas implémentée. Peut-être dans une nouvelle version des pandas. Ensuite, ma réponse sera mise à jour.
Utilisez pd.concat()
comme suit:
#Split into separate tables
df_1 = df[['A', 'B']]
df_2 = df[['A1', 'B1']]
df_2.columns = ['A', 'B'] # Make column names line up
# Add the ID column
df_1 = df_1.assign(id=1)
df_2 = df_2.assign(id=2)
# Concatenate
pd.concat([df_1, df_2])
J'ai résolu ceci en 3 étapes:
df2
contenant uniquement les données que vous souhaitez ajouter au cadre de données initial df
.df
qui seront ajoutées ci-dessous (et qui ont été utilisées pour créer df2
.df2
à df
.Ainsi:
# step 1: create new dataframe
df2 = df[['A1', 'B1']]
df2.columns = ['A', 'B']
# step 2: delete that data from original
df = df.drop(["A1", "B1"], 1)
# step 3: append
df = df.append(df2, ignore_index=True)
Notez que lorsque vous faites df.append()
vous devez spécifier ignore_index=True
pour que les nouvelles colonnes soient ajoutées à l'index plutôt que de conserver leur ancien index.
Votre résultat final doit être votre image d'origine avec les données réorganisées comme vous le souhaitez:
In [16]: df
Out[16]:
A B
0 1 2
1 5 6
2 9 10
3 3 4
4 7 8
5 11 12