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

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

Ответ 1

Как @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

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

Ответ 3

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

Как вы можете видеть:

enter image description here