Панды: разбор DataFrame в серии вызывает NaN - PullRequest
0 голосов
/ 30 октября 2018

У меня есть следующий фрейм данных, и я хочу снять его, получив серию x и серию y с time в качестве индекса и value в качестве данных:

   var  time  value
0    x     0     11
1    y     0    123
2    x     1     12
3    y     1    124
4    x     2     13
5    y     2    125

Это мой код:

import pandas as pd

df = pd.DataFrame({
        'time': [0,0,1,1,2,2],
        'var': list('xyxyxy'),
        'value': [11,123,12,124,13,125]})

for col in ['x', 'y']:
    s = pd.Series(
            data=df.loc[df['var'] == col, 'value'],
            index=df.loc[df['var'] == col, 'time'],
            name=col)
    print(s)

Это вывод:

time
0    11.0
1     NaN
2    12.0
Name: x, dtype: float64

time
0      NaN
1    123.0
2      NaN
Name: y, dtype: float64

Но я ожидаю, что сериал будет

time
0    11.0
1    12.0 
2    13.0
Name: x, dtype: float64

time
0    123.0
1    124.0
2    125.0
Name: y, dtype: float64

Очевидно, что панды неправильно совмещают ось time с осью value. Насколько я понимаю, каждый .loc должен просто вернуть соответствующие 3 элемента и собрать их вместе в качестве индекса и данных для вновь созданного ряда.

  1. Почему этого не происходит?
  2. Какой самый простой способ получить желаемый результат?

Ответы [ 3 ]

0 голосов
/ 30 октября 2018

Это pivot проблема

s=df.pivot(*df.columns)
s
Out[56]: 
time    0    1    2
var                
x      11   12   13
y     123  124  125

#s['y'],s['x']
0 голосов
/ 30 октября 2018

Есть лучшие способы добиться этого, как указывал @Wen. Если вам интересно, что не так с вашим кодом, вы передаете серию в виде данных и индекса, вместо этого передайте массив.

for v in df['var'].unique():
    s = pd.Series(
        data=df.loc[df['var'] == v, 'value'].values,
        index=df.loc[df['var'] == v, 'time'].values,
        name=col)
    print(s)

0    11
1    12
2    13
Name: y, dtype: int64
0    123
1    124
2    125
Name: y, dtype: int64
0 голосов
/ 30 октября 2018

Я не уверен, почему указание Серии в качестве данных дает вам такой результат, но я могу ответить на ваш второй вопрос

  1. Какой самый простой способ получить желаемый результат?

Вы можете преобразовать свои данные в список, чтобы получить желаемый результат.

for col in ['x', 'y']:
    s = pd.Series(
            data=df.loc[df['var'] == col, 'value'].tolist(),
            index=df.loc[df['var'] == col, 'time'],
            name=col)
    print(s)

Выход:

time
0    11
1    12
2    13
Name: x, dtype: int64
time
0    123
1    124
2    125
Name: y, dtype: int64

Вот еще один способ, похожий на ответ, представленный @Wen (и более элегантный):

df_new = pd.pivot_table(data=df, columns='var', index='time', values='value')

Выход:

var    x    y
time         
0     11  123
1     12  124
2     13  125

Тогда вы можете позвонить df_new['x'] или df_new['y'].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...