Панди Python: зберегти вибраний стовпець як DataFrame замість Series


92

При виборі одного стовпчика з панд DataFrame (скажімо df.iloc[:, 0], df['A']або df.A, і т.д.), результуючий вектор автоматично перетворюються в серії замість одного стовпчика DataFrame. Однак я пишу деякі функції, які приймають 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
Вибачте, що вас турбую, але дуже швидке запитання щодо цього. Я бачу, як екстра []робить результат 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

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], в цьому випадку отриманий вектор буде a, 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 серія не матиме гарного виводу, але кадр даних буде.

# 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.