Tenez compte de la trame de données df
df = pd.DataFrame(dict(A=[1, 2], B=['X', 'Y']))
df
A B
0 1 X
1 2 Y
Si je me déplace axis=0
(par défaut)
df.shift()
A B
0 NaN NaN
1 1.0 X
Il pousse toutes les lignes vers le bas d'une ligne comme prévu.
Mais quand je me déplace axis=1
df.shift(axis=1)
A B
0 NaN NaN
1 NaN NaN
Tout est nul quand je m'y attendais
A B
0 NaN 1
1 NaN 2
Je comprends pourquoi cela s'est produit. Pour axis=0
, Pandas fonctionne colonne par colonne où chaque colonne est unique dtype
et lors du déplacement, il existe un protocole clair sur la façon de traiter la NaN
valeur introduite au début ou à la fin. Mais lorsque axis=1
nous nous déplaçons, nous introduisons une ambiguïté potentielle d' dtype
une colonne à l'autre. Dans ce cas, j'essaie de forcer int64
dans une object
colonne et Pandas décide de simplement annuler les valeurs.
Cela devient plus problématique lorsque le dtypes
sont int64
etfloat64
df = pd.DataFrame(dict(A=[1, 2], B=[1., 2.]))
df
A B
0 1 1.0
1 2 2.0
Et la même chose se produit
df.shift(axis=1)
A B
0 NaN NaN
1 NaN NaN
Ma question
Quelles sont les bonnes options pour créer une trame de données qui est décalée le long axis=1
de laquelle le résultat a décalé les valeurs et les dtypes?
Pour le cas int64
/ float64
, le résultat ressemblerait à:
df_shifted
A B
0 NaN 1
1 NaN 2
et
df_shifted.dtypes
A object
B int64
dtype: object
Un exemple plus complet
df = pd.DataFrame(dict(A=[1, 2], B=[1., 2.], C=['X', 'Y'], D=[4., 5.], E=[4, 5]))
df
A B C D E
0 1 1.0 X 4.0 4
1 2 2.0 Y 5.0 5
Devrait ressembler à ceci
df_shifted
A B C D E
0 NaN 1 1.0 X 4.0
1 NaN 2 2.0 Y 5.0
df_shifted.dtypes
A object
B int64
C float64
D object
E float64
dtype: object
object
?object
blocks
>. <Utilisez-le à la place et voyezdf = pd.DataFrame(dict(A=[1, 2], B=[3., 4.], C=['X', 'Y'], D=[5., 6.], E=[7, 8], F=['W', 'Z']))
Réponses:
Il s'avère que les Pandas se déplacent sur des blocs de
dtypes
Définir
df
commeIl déplacera les entiers vers la colonne entière suivante, les flottants vers la colonne flottante suivante et les objets vers la colonne objet suivante
Je ne sais pas si c'est une bonne idée, mais c'est ce qui se passe.
Approches
astype(object)
premièretranspose
Le fera
object
itertuples
Bien que je ferais probablement ça
la source
str
dytpes, alors cela fonctionne correctement, si vous faites la même chose sur ce df,df = pd.DataFrame(dict(C=['X', 'Y'], D=[5., 6.], E=[7, 8], F=['W', 'Z']))
cela déplace la'XY'
colonne complètement vers la'F'
colonne, c'est définitivement faux pour moi, ma version pandas est0.24.2
, elle devrait faire de ladtype
promotion et ne pas déplacer les colonnes dans un tel un moyenJ'ai essayé d'utiliser une
numpy
méthode. La méthode fonctionne tant que vous conservez vos données dans un tableau numpy:Mais lorsque vous appelez le
DataFrame
constructeur, toutes les colonnes sont converties enobject
bien que les valeurs du tableau soientfloat, int, object
:la source