При выборе одного столбца из фрейма данных pandas (скажем df.iloc[:, 0]
, df['A']
или df.A
и т. Д.) Результирующий вектор автоматически преобразуется в серию, а не в фрейм данных с одним столбцом. Однако я пишу некоторые функции, которые принимают DataFrame в качестве входного аргумента. Поэтому я предпочитаю иметь дело с DataFrame с одним столбцом вместо Series, чтобы функция могла предположить, что df.columns доступен. Прямо сейчас мне нужно явно преобразовать серию в DataFrame, используя что-то вроде pd.DataFrame(df.iloc[:, 0])
. Это не кажется самым чистым методом. Есть ли более элегантный способ индексирования непосредственно из DataFrame, чтобы в результате получился DataFrame с одним столбцом вместо Series?
92
Ответы:
Как упоминает @Jeff, есть несколько способов сделать это, но я рекомендую использовать loc / iloc, чтобы быть более явным (и рано вызывать ошибки, если вы пытаетесь что-то двусмысленное):
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
Последние два варианта устраняют двусмысленность в случае целочисленных имен столбцов (именно поэтому были созданы loc / iloc). Например:
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
источник
[]
делает результат aDataFrame
вместо aSeries
, но где в документах pandas обсуждается такой синтаксис индексации? Я просто пытаюсь получить «официальное» название этой техники индексации, чтобы я действительно ее понял. Спасибо!Как рекомендует Энди Хейден , использование .iloc / .loc для индексации (с одной колонкой) фрейма данных - лучший способ; еще один момент, который следует отметить, - как выразить позиции индекса. Используйте перечисленные метки / позиции индекса при указании значений аргументов для индексации как Dataframe; в противном случае будет возвращено 'pandas.core.series.Series'
Вход:
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))
Выход:
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'>
источник
Вы можете использовать
df.iloc[:, 0:1]
, в этом случае результирующий вектор будетDataFrame
не серией, а серией.Как вы видете:
источник
Были упомянуты эти три подхода:
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 () - другой подход.
Поскольку это метод, его можно использовать в ситуациях, когда второй и третий подходы выше не применимы. В частности, это полезно при применении какого-либо метода к столбцу в фрейме данных, и вы хотите преобразовать вывод в фрейм данных вместо ряда. Например, в Jupyter Notebook серия не будет иметь хороших результатов, но фрейм данных будет.
# 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()
источник