Перетворити фрейм даних панд на серії


99

Я дещо новачок у пандах. У мене є кадр даних pandas, який становить 1 рядок на 23 стовпці.

Я хочу перетворити це на серію? Цікаво, який найбільш пітонічний спосіб це зробити?

Я пробував, pd.Series(myResults)але це скаржиться ValueError: cannot copy sequence with size 23 to array axis with dimension 1. Це недостатньо розумно, щоб усвідомити, що це все ще "вектор" в математичному плані.

Дякую!

Відповіді:


64

Це недостатньо розумно, щоб усвідомити, що це все ще "вектор" в математичному плані.

Скажіть швидше, що це досить розумно, щоб розпізнати різницю в розмірності. :-)

Я думаю, що найпростіше, що ви можете зробити, це вибрати цей рядок позиційно, використовуючи це iloc, що дає вам Серію зі стовпцями як новим індексом і значеннями як значення:

>>> df = pd.DataFrame([list(range(5))], columns=["a{}".format(i) for i in range(5)])
>>> df
   a0  a1  a2  a3  a4
0   0   1   2   3   4
>>> df.iloc[0]
a0    0
a1    1
a2    2
a3    3
a4    4
Name: 0, dtype: int64
>>> type(_)
<class 'pandas.core.series.Series'>

2
Або інший спосіб:df.T
АКО

14
@ako: df.Tне створює Серію, однак, просто транспонований DataFrame.
DSM,

@DSM. Це правда, df.T.iloc [0]
Антоніо Андрес

Єдина проблема використання df.ilocполягає в тому, що якщо у вас порожній df, це призведе до IndexError. Щоб цього уникнути, після транспонування вашого df використовуйте df.squeezeметод. Посилання до pandas.pydata.org/pandas-docs/stable/reference/api/…
Ніколас Фонтейне

61

Ви можете транспонувати однорядовий фрейм даних (що все одно призводить до фрейму даних), а потім стиснути результати в ряд (обернене до to_frame).

df = pd.DataFrame([list(range(5))], columns=["a{}".format(i) for i in range(5)])

>>> df.T.squeeze()  # Or more simply, df.squeeze() for a single row dataframe.
a0    0
a1    1
a2    2
a3    3
a4    4
Name: 0, dtype: int64

Примітка: Щоб врахувати питання, підняте @IanS (навіть якщо це не в запитанні OP), протестуйте розмір кадру даних. Я припускаю, що dfце фрейм даних, але випадки ребер - це порожній фрейм даних, фрейм даних фігури (1, 1) та фрейм даних з більш ніж одним рядком, і в цьому випадку використання має реалізувати бажану функціональність.

if df.empty:
    # Empty dataframe, so convert to empty Series.
    result = pd.Series()
elif df.shape == (1, 1)
    # DataFrame with one value, so convert to series with appropriate index.
    result = pd.Series(df.iat[0, 0], index=df.columns)
elif len(df) == 1:
    # Convert to series per OP's question.
    result = df.T.squeeze()
else:
    # Dataframe with multiple rows.  Implement desired behavior.
    pass

Це також можна спростити у відповідності до відповіді, наданої @themachinist.

if len(df) > 1:
    # Dataframe with multiple rows.  Implement desired behavior.
    pass
else:
    result = pd.Series() if df.empty else df.iloc[0, :]

11
Зверніть увагу, що я зіткнувся з невеликою проблемою за допомогою squeeze. Для кадру даних форми (1, 1)він поверне не серію довжиною 1, а нуме скаляр. Це призвело до важкоуловимої помилки при використанні squeezeна об'єктах невідомої довжини (наприклад, з groupby).
IanS

2
"Дякую! Df.squeeze () спрацював, коли df.iloc [:, 0] & df.ix [:, 0] обидва видали занадто багато помилок індексів"
Afflatus

3
А чому зворотне значення to_frameні to_seriesчи pd.Series(df)...?
jhin,

4
Вам не потрібно.T
elgehelge

1
@IanS передає аргумент df.squeeze(axis=0)або df.squeeze(axis=1)(залежно від осі, яку потрібно зберегти), щоб уникнути цього
Ніколас Фонтейне

33

Ви можете отримати серію шляхом нарізання вашого кадру даних одним із цих двох методів:

http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.iloc.html http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.loc.html

import pandas as pd
import numpy as np
df = pd.DataFrame(data=np.random.randn(1,8))

series1=df.iloc[0,:]
type(series1)
pandas.core.series.Series

4

Інший спосіб -

Припустимо, myResult - це dataFrame, який містить ваші дані у вигляді 1 колон та 23 рядків

// label your columns by passing a list of names
myResult.columns = ['firstCol']

// fetch the column in this way, which will return you a series
myResult = myResult['firstCol']

print(type(myResult))

Подібним чином ви можете отримати серії з Dataframe з кількома стовпцями.


3

Ви також можете використовувати stack ()

df= DataFrame([list(range(5))], columns = [“a{}”.format(I) for I in range(5)])

Після u запустіть df, а потім запустіть:

df.stack()

Ви отримуєте свій кадр даних послідовно


0
data = pd.DataFrame({"a":[1,2,3,34],"b":[5,6,7,8]})
new_data = pd.melt(data)
new_data.set_index("variable", inplace=True)

Це дає фрейм даних з індексом як ім'ям стовпця даних, і всі дані присутні в стовпці "значення"


5
Ласкаво просимо до Stack Overflow! Як це відповідає на питання? Ваш код не повертає серію, як запитання
Gricey
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.