Po wybraniu pojedynczej kolumny z pandy DataFrame (powiedzmy df.iloc[:, 0]
, df['A']
lub df.A
, itp.), Wynikowy wektor jest automatycznie konwertowany na Series zamiast na pojedynczą kolumnę DataFrame. Jednak piszę niektóre funkcje, które przyjmują DataFrame jako argument wejściowy. Dlatego wolę zajmować się pojedynczą kolumną DataFrame zamiast Series, aby funkcja mogła założyć, że df.columns jest dostępne. W tej chwili muszę jawnie przekonwertować Series na DataFrame, używając czegoś takiego jak pd.DataFrame(df.iloc[:, 0])
. To nie wydaje się najczystszą metodą. Czy istnieje bardziej elegancki sposób indeksowania bezpośrednio z DataFrame, tak aby wynik był jednokolumnowym DataFrame zamiast Series?
92
Odpowiedzi:
Jak wspomina @Jeff, jest kilka sposobów, aby to zrobić, ale polecam użycie loc / iloc, aby być bardziej wyraźnym (i zgłaszać błędy wcześniej, jeśli próbujesz czegoś niejednoznacznego):
In [10]: df = pd.DataFrame([[1, 2], [3, 4]], columns=['A', 'B']) In [11]: df Out[11]: A B 0 1 2 1 3 4 In [12]: df[['A']] In [13]: df[[0]] In [14]: df.loc[:, ['A']] In [15]: df.iloc[:, [0]] Out[12-15]: # they all return the same thing: A 0 1 1 3
Dwie ostatnie opcje eliminują niejednoznaczność w przypadku nazw kolumn zawierających liczby całkowite (właśnie dlatego utworzono loc / iloc). Na przykład:
In [16]: df = pd.DataFrame([[1, 2], [3, 4]], columns=['A', 0]) In [17]: df Out[17]: A 0 0 1 2 1 3 4 In [18]: df[[0]] # ambiguous Out[18]: A 0 1 1 3
źródło
[]
sprawia, że wynik jest aDataFrame
zamiast aSeries
, ale gdzie w dokumentach pandy omawia się ten rodzaj składni indeksowania? Po prostu próbuję uzyskać „oficjalną” nazwę tej techniki indeksowania, aby naprawdę ją zrozumieć. Dzięki!Jak zaleca Andy Hayden , najlepszym rozwiązaniem jest wykorzystanie plików .iloc / .loc do indeksowania (jednokolumnowej) ramki danych; Kolejną kwestią, na którą należy zwrócić uwagę, jest sposób wyrażania pozycji indeksu. Użyj wymienionych etykiet / pozycji indeksu podczas określania wartości argumentów do indeksowania jako Dataframe; w przeciwnym razie zostanie zwrócony plik „pandas.core.series.Series”
Wejście:
A_1 = train_data.loc[:,'Fraudster'] print('A_1 is of type', type(A_1)) A_2 = train_data.loc[:, ['Fraudster']] print('A_2 is of type', type(A_2)) A_3 = train_data.iloc[:,12] print('A_3 is of type', type(A_3)) A_4 = train_data.iloc[:,[12]] print('A_4 is of type', type(A_4))
Wynik:
A_1 is of type <class 'pandas.core.series.Series'> A_2 is of type <class 'pandas.core.frame.DataFrame'> A_3 is of type <class 'pandas.core.series.Series'> A_4 is of type <class 'pandas.core.frame.DataFrame'>
źródło
Możesz użyć
df.iloc[:, 0:1]
, w tym przypadku wynikowy wektor będzieDataFrame
serią, a nie serią.Jak widzisz:
źródło
Wspomniano o tych trzech podejściach:
pd.DataFrame(df.loc[:, 'A']) # Approach of the original post df.loc[:,[['A']] # Approach 2 (note: use iloc for positional indexing) df[['A']] # Approach 3
pd.Series.to_frame () to inne podejście.
Ponieważ jest to metoda, można ją zastosować w sytuacjach, w których nie ma zastosowania drugie i trzecie podejście powyżej. W szczególności jest to przydatne podczas stosowania jakiejś metody do kolumny w ramce danych i chcesz przekonwertować wynik na ramkę danych zamiast na serię. Na przykład w notatniku Jupyter seria nie będzie miała ładnych wyników, ale ramka danych będzie.
# Basic use case: df['A'].to_frame() # Use case 2 (this will give you pretty output in a Jupyter Notebook): df['A'].describe().to_frame() # Use case 3: df['A'].str.strip().to_frame() # Use case 4: def some_function(num): ... df['A'].apply(some_function).to_frame()
źródło