Rozważ ramkę danych df
df = pd.DataFrame(dict(A=[1, 2], B=['X', 'Y']))
df
A B
0 1 X
1 2 Y
Jeśli przejdę dalej axis=0
(domyślnie)
df.shift()
A B
0 NaN NaN
1 1.0 X
Przesuwa wszystkie rzędy o jeden rząd w dół zgodnie z oczekiwaniami.
Ale kiedy się zmieniam axis=1
df.shift(axis=1)
A B
0 NaN NaN
1 NaN NaN
Wszystko jest zerowe, kiedy się spodziewałem
A B
0 NaN 1
1 NaN 2
Rozumiem, dlaczego tak się stało. Ponieważ axis=0
Panda działa kolumna po kolumnie, gdzie każda kolumna jest pojedyncza, dtype
a podczas przesuwania istnieje jasny protokół, w jaki sposób radzić sobie z wprowadzoną NaN
wartością na początku lub na końcu. Ale przechodząc dalej axis=1
, wprowadzamy potencjalną niejednoznaczność dtype
jednej kolumny do drugiej. W tym przypadku próbuję wymusić int64
wprowadzenie do object
kolumny, a Panda postanawia po prostu zerować wartości.
Staje się to bardziej problematyczne, gdy dtypes
są int64
ifloat64
df = pd.DataFrame(dict(A=[1, 2], B=[1., 2.]))
df
A B
0 1 1.0
1 2 2.0
I to samo się dzieje
df.shift(axis=1)
A B
0 NaN NaN
1 NaN NaN
Moje pytanie
Jakie są dobre opcje tworzenia ramek danych, które są przesuwane, axis=1
w których wynik ma przesunięte wartości i typy?
W przypadku int64
/ float64
wynik wygląda następująco:
df_shifted
A B
0 NaN 1
1 NaN 2
i
df_shifted.dtypes
A object
B int64
dtype: object
Bardziej kompleksowy przykład
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
Powinno tak wyglądać
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
>. <Zamiast tego użyj tego i zobaczdf = pd.DataFrame(dict(A=[1, 2], B=[3., 4.], C=['X', 'Y'], D=[5., 6.], E=[7, 8], F=['W', 'Z']))
Odpowiedzi:
Okazuje się, że Pandy przesuwają się po blokach podobnych
dtypes
Zdefiniuj
df
jakoPrzeniesie liczby całkowite do następnej kolumny liczb całkowitych, przestawi się do następnej kolumny przestawnej, a obiekty do następnej kolumny obiektów
Nie wiem, czy to dobry pomysł, ale to jest to, co się dzieje.
Podejścia
astype(object)
pierwszytranspose
Zrobię to
object
itertuples
Chociaż prawdopodobnie to zrobiłbym
źródło
str
dytpy, to działa poprawnie, jeśli zrobisz to samo na tym dfdf = pd.DataFrame(dict(C=['X', 'Y'], D=[5., 6.], E=[7, 8], F=['W', 'Z']))
, przesuwa'XY'
kolumnę do samej'F'
kolumny, to zdecydowanie jest dla mnie źle, moja wersja pand jest taka0.24.2
, że powinnadtype
promować i nie przesuwać kolumn w takich sposóbPróbowałem użyć
numpy
metody. Metoda działa tak długo, jak długo przechowujesz dane w tablicy numpy:Ale po wywołaniu
DataFrame
konstruktora wszystkie kolumny są konwertowane na,object
chociaż wartości w tablicy są następującefloat, int, object
:źródło