Панды: переиндексируйте и интерполируйте в многоиндексном фрейме данных - PullRequest
0 голосов
/ 15 декабря 2018

У меня проблемы с пониманием панд reindex.У меня есть серия измерений, объединенная в многоиндексный df, и я хотел бы переиндексировать и интерполировать эти измерения, чтобы выровнять их с некоторыми другими данными.

Мои фактические данные имеют ~ 7 уровней индексаи несколько разных измерений.Я надеюсь, что решение этой проблемы с игрушками применимо к моим реальным данным.Это «маленькие данные»;каждое отдельное измерение - это пара КБ.

Вот пара игрушечных задач, одна из которых показывает ожидаемое поведение, а другая, похоже, ничего не делает.

Одноуровневый индекс, работаеткак и ожидалось:

"""
step,value
1,1
3,2
5,1
"""
df_i = pd.read_clipboard(sep=",").set_index("step")
print(df_i)

new_index = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])

df_i = df_i.reindex(new_index).interpolate()
print(df_i)

Выходы, исходный df и индексированный и интерполированный:

      value
step       
1         1
3         2
5         1
      value
step       
1       1.0
2       1.5
3       2.0
4       1.5
5       1.0
6       1.0
7       1.0
8       1.0
9       1.0

Отлично работает.

Многоиндексный, в настоящее время нетработает:

"""
sample,meas_id,step,value
1,1,1,1
1,1,3,2
1,1,5,1
1,2,3,2
1,2,5,2
1,2,7,1
1,2,9,0
"""
df_mi = pd.read_clipboard(sep=",").set_index(["sample", "meas_id", "step"])
print(df_mi)

df_mi = df_mi.reindex(new_index, level="step").interpolate()
print(df_mi)

Вывод, без изменений после переиндексации (и, следовательно, после интерполяции):

                     value
sample meas_id step       
1      1       1         1
               3         2
               5         1
       2       3         2
               5         2
               7         1
               9         0


                     value
sample meas_id step       
1      1       1         1
               3         2
               5         1
       2       3         2
               5         2
               7         1
               9         0

Как мне на самом деле переиндексировать столбец в мультииндексеdf?

Вот вывод, который я хотел бы, предполагая линейную интерполяцию:

                     value
sample meas_id step       
1      1       1         1
               2       1.5
               3         2
               5         1
               6         1
               7         1
               8         1
               9         1
       2       1       NaN (or 2)
               2       NaN (or 2)
               3         2
               4         2
               5         2
               6       1.5
               7         1
               8       0.5
               9         0

Я провел некоторое искреннее время, просматривая SO, и, если ответ там, я пропустил его:

Заполнить мультииндексный DataFrame Pandas с интерполяцией

Повторная выборка в мультииндексе Pandas

pandas multiindex dataframe,ND-интерполяция для пропущенных значений

Заполнить многоиндексный панорамированиеdas DataFrame с интерполяцией

https://pandas.pydata.org/pandas-docs/stable/basics.html#basics-reindexing

Возможные проблемы с GitHub:

https://github.com/numpy/numpy/issues/11975

https://github.com/pandas-dev/pandas/issues/23104

https://github.com/pandas-dev/pandas/issues/17132

1 Ответ

0 голосов
/ 15 декабря 2018

IIUC создайте индекс с помощью MultiIndex.from_product, затем просто выполните reindex

idx=pd.MultiIndex.from_product([df_mi.index.levels[0],df_mi.index.levels[1],new_index])    
df_mi.reindex(idx).interpolate()
Out[161]: 
          value
1 1 1  1.000000
    2  1.500000
    3  2.000000
    4  1.500000
    5  1.000000
    6  1.142857
    7  1.285714
    8  1.428571
    9  1.571429
  2 1  1.714286 # here is bad , it take previous value into consideration 
    2  1.857143
    3  2.000000
    4  2.000000
    5  2.000000
    6  1.500000
    7  1.000000
    8  0.500000
    9  0.000000

Я думаю

def idx(x):
    idx = pd.MultiIndex.from_product([x.index.get_level_values(0).unique(), x.index.get_level_values(1).unique(), new_index])
    return idx



pd.concat([y.reindex(idx(y)).interpolate() for _,y in df_mi.groupby(level=[0,1])])

       value
1 1 1    1.0
    2    1.5
    3    2.0
    4    1.5
    5    1.0
    6    1.0
    7    1.0
    8    1.0
    9    1.0
  2 1    NaN
    2    NaN
    3    2.0
    4    2.0
    5    2.0
    6    1.5
    7    1.0
    8    0.5
    9    0.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...