Повторная выборка данных, не относящихся к временным рядам

У меня есть некоторые данные, которые я обрабатываю с помощью фреймов данных и панд. Они содержат около 10 000 строк и 6 столбцов.

Проблема в том, что я провел несколько испытаний, и разные наборы данных имеют несколько разные номера индексов. (Это испытание "длина-сила" с несколькими материалами и, конечно, точки измерения не выровнены идеально.)

Теперь моя идея состояла в том, чтобы "пересчитать" данные, используя индекс, который содержит значение длины. Кажется, что функция передискретизации в пандах доступна только для типов данных datetime.

Я попытался преобразовать индекс через to_datetime и успешно. Но после пересчета мне нужно вернуться к исходному масштабу. какая-то функция from_datetime.

Есть ли какой-либо способ, или я нахожусь на совершенно неправильном пути и должен лучше использовать такие функции, как groupby?

Изменить, чтобы добавить:

Данные замки, как показано ниже. Длина используется в качестве индекса. Из этих Dataframes у меня есть несколько, так что было бы очень приятно выровнять их все по одной и той же "частоте кадров", а затем вырезать их, например, чтобы я мог сравнить разные наборы данных.

Идея, которую я уже попробовал, была такой:

    df_1_dt = df_1 #generate a table for the conversion
    df_1_dt.index = pd.to_datetime(df_1_dt.index, unit='s') # convert it simulating seconds.. good idea?!
    df_1_dt_rs= df_1_dt # generate a df for the resampling
    df_1_dt_rs = df_1_dt_rs.resample (rule='s') #resample by the generatet time

Данные:

+---------------------------------------------------+  
¦  Index (Lenght)   ¦    Force1     ¦    Force2     ¦  
¦-------------------+---------------+---------------¦  
¦ 8.04662074828e-06 ¦ 4.74251270294 ¦ 4.72051584721 ¦  
¦ 8.0898882798e-06  ¦ 4.72051584721 ¦ 4.72161570191 ¦  
¦ 1.61797765596e-05 ¦ 4.69851899147 ¦ 4.72271555662 ¦  
¦ 1.65476570973e-05 ¦ 4.65452528    ¦ 4.72491526604 ¦  
¦ 2.41398605024e-05 ¦ 4.67945501539 ¦ 4.72589291467 ¦  
¦ 2.42696630876e-05 ¦ 4.70438475079 ¦ 4.7268705633  ¦  
¦ 9.60953101751e-05 ¦ 4.72931448619 ¦ 4.72784821192 ¦  
¦ 0.00507703541206  ¦ 4.80410369237 ¦ 4.73078115781 ¦  
¦ 0.00513927175509  ¦ 4.87889289856 ¦ 4.7337141037  ¦  
¦ 0.00868965311878  ¦ 4.9349848032  ¦ 4.74251282215 ¦  
¦ 0.00902026197556  ¦ 4.99107670784 ¦ 4.7513115406  ¦  
¦ 0.00929150878827  ¦ 5.10326051712 ¦ 4.76890897751 ¦  
¦ 0.0291729332784   ¦ 5.14945375919 ¦ 4.78650641441 ¦  
¦ 0.0296332588857   ¦ 5.17255038023 ¦ 4.79530513287 ¦  
¦ 0.0297080942518   ¦ 5.19564700127 ¦ 4.80410385132 ¦  
¦ 0.0362595526707   ¦ 5.2187436223  ¦ 4.80850321054 ¦  
¦ 0.0370305483177   ¦ 5.24184024334 ¦ 4.81290256977 ¦  
¦ 0.0381506204153   ¦ 5.28803348541 ¦ 4.82170128822 ¦  
¦ 0.0444440795306   ¦ 5.30783069134 ¦ 4.83050000668 ¦  
¦ 0.0450121369102   ¦ 5.3177292943  ¦ 4.8348993659  ¦  
¦ 0.0453465140473   ¦ 5.32762789726 ¦ 4.83929872513 ¦  
¦ 0.0515533437013   ¦ 5.33752650023 ¦ 4.85359662771 ¦  
¦ 0.05262489708     ¦ 5.34742510319 ¦ 4.8678945303  ¦  
¦ 0.0541273847206   ¦ 5.36722230911 ¦ 4.89649033546 ¦  
¦ 0.0600755845953   ¦ 5.37822067738 ¦ 4.92508614063 ¦  
¦ 0.0607712385295   ¦ 5.38371986151 ¦ 4.93938404322 ¦  
¦ 0.0612954159368   ¦ 5.38921904564 ¦ 4.9536819458  ¦  
¦ 0.0670288249293   ¦ 5.39471822977 ¦ 4.97457891703 ¦  
¦ 0.0683640870058   ¦ 5.4002174139  ¦ 4.99547588825 ¦  
¦ 0.0703192637772   ¦ 5.41121578217 ¦ 5.0372698307  ¦  
¦ 0.0757871634772   ¦ 5.43981158733 ¦ 5.07906377316 ¦  
¦ 0.0766597757545   ¦ 5.45410948992 ¦ 5.09996074438 ¦  
¦ 0.077317850103    ¦ 5.4684073925  ¦ 5.12085771561 ¦  
¦ 0.0825991083545   ¦ 5.48270529509 ¦ 5.13295596838 ¦  
¦ 0.0841354654428   ¦ 5.49700319767 ¦ 5.14505422115 ¦  
¦ 0.0865525182528   ¦ 5.52559900284 ¦ 5.1692507267  ¦  
+---------------------------------------------------+  

Ответ 1

Похоже, что все, что вы хотите сделать, это округлить фигуры до более низкой точности.

Если это так, вы можете просто использовать встроенную функцию округления:

(фиктивные данные)

>>> df=pd.DataFrame([[1.0000005,4],[1.232463632,5],[5.234652,9],[5.675322,10]],columns=['length','force'])
>>> df
33:      length  force
0  1.000001      4
1  1.232464      5
2  5.234652      9
3  5.675322     10
>>> df['rounded_length'] = df.length.apply(round, ndigits=0)
>>> df
34:      length  force  rounded_length
0  1.000001      4             1.0
1  1.232464      5             1.0
2  5.234652      9             5.0
3  5.675322     10             6.0
>>> 

Затем вы можете реплицировать рабочий процесс resample().... с помощью groupby:

>>> df.groupby('rounded_length').mean().force
35: rounded_length
1.0     4.5
5.0     9.0
6.0    10.0
Name: force, dtype: float64

Как правило, resample IS только для дат. Если вы используете его для чего-то другого, кроме дат, возможно, более элегантное решение!

Ответ 2

У меня была очень похожая проблема с вами, и я нашел решение. Решение по существу

Интегрировать → Интерполировать → Дифференцировать

Сначала я опишу проблему, которую решаю, чтобы убедиться, что мы находимся на одной странице. Простой пример: если у вас есть точки (x1, y1) и (x2, y2), и вы хотите (x0 ', y0'), (x1 ', y1') (вы знаете x0 ', x1' и хотите найти y1 '), с x0' <x1 <x1 '<x2, то вы хотите взять средневзвешенное значение, поэтому y1' = ((x1 '- x1) * y2 + (x1 - x0') * y1)/(x1 '- x0').

Способ сделать это - интегрировать, затем интерполировать, а затем дифференцировать. Скажем, у вас есть фрейм данных со столбцами 'x' и 'y', но вы хотите пересэмплировать к новому x new_x, который является numpy.ndarray.

df['integral'] = (df['y'] * (df['x'] - df['x'].shift(1))).cumsum()
new_integral = np.interp(new_x, df['x'].values, df['integral'].values, left=0., right=np.nan)
new = pd.DataFrame({'new_x': new_x, 'integral': new_integral})
new['y'] = (new['integral'] - new['integral'].shift(1)) / (new['new_x'] - new['new_x'].shift(1))

Я бы начал new_x с 0. а затем отбросил первое значение из нового фрейма данных, потому что это будет NaN. Вы также можете заполнить и завершить NaN на высоком х с любым, что вы хотите.

Я надеюсь, что это решит вашу проблему. Я не включил доказательство того, что этот метод решает проблему, определенную выше, но это не трудно показать.