Python pandas: сохранить выбранный столбец как DataFrame вместо Series


92

При выборе одного столбца из фрейма данных pandas (скажем df.iloc[:, 0], df['A']или df.Aи т. Д.) Результирующий вектор автоматически преобразуется в серию, а не в фрейм данных с одним столбцом. Однако я пишу некоторые функции, которые принимают DataFrame в качестве входного аргумента. Поэтому я предпочитаю иметь дело с DataFrame с одним столбцом вместо Series, чтобы функция могла предположить, что df.columns доступен. Прямо сейчас мне нужно явно преобразовать серию в DataFrame, используя что-то вроде pd.DataFrame(df.iloc[:, 0]). Это не кажется самым чистым методом. Есть ли более элегантный способ индексирования непосредственно из DataFrame, чтобы в результате получился DataFrame с одним столбцом вместо Series?


6
df.iloc [:, [0]] или df [['A']]; df.A only вернет серию, однако
Джефф

Ответы:


99

Как упоминает @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

2
Извините, что беспокою вас, но просто быстрый вопрос по этому поводу. Я вижу, как дополнительный []делает результат a DataFrameвместо a Series, но где в документах pandas обсуждается такой синтаксис индексации? Я просто пытаюсь получить «официальное» название этой техники индексации, чтобы я действительно ее понял. Спасибо!
sparc_spread

3
@sparc_spread pandas.pydata.org/pandas-docs/stable/indexing.html#basics «Вы можете передать список столбцов в [], чтобы выбрать столбцы в указанном порядке». Я не уверен, есть ли у этого имя!
Энди Хайден

Да, похоже, у него его нет, но с этого момента я буду использовать его. Удивительно, сколько всего похоронено как в API, так и в документации. Спасибо!
sparc_spread

Это различие было полезно для меня, потому что иногда мне нужен DataFrame с одним столбцом, чтобы я мог использовать методы DataFrame для данных, которые были недоступны в Series. (ISTR метод сюжета вел себя иначе). Для меня это было озарением, когда я понял, что могу использовать одноэлементный список!
RufusVS 03

4

Как рекомендует Энди Хейден , использование .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'>

1

Вы можете использовать df.iloc[:, 0:1], в этом случае результирующий вектор будетDataFrame не серией, а серией.

Как вы видете:

введите описание изображения здесь


1

Были упомянуты эти три подхода:

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()
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.