Преобразование фрейма данных pandas в серию


98

Я новичок в пандах. У меня есть кадр данных 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
ako

14
@ako: df.Tне создает Series, а просто транспонированный DataFrame.
DSM

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

Единственная проблема с использованием df.ilocзаключается в том, что если у вас пустой df, это вызовет расширение IndexError. Чтобы избежать этого, после транспонирования вашего df используйте df.squeezeметод. Ref. to pandas.pydata.org/pandas-docs/stable/reference/api/…
Николас Фонтейн,

60

Вы можете транспонировать однорядный фрейм данных (который по-прежнему дает фрейм данных), а затем сжать результаты в ряд (обратный 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)])

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