【问题标题】:Pandas: linearly interpolate multiple steps between multiple columnsPandas:在多列之间线性插值多个步骤
【发布时间】:2020-02-26 14:45:09
【问题描述】:

我一直在这里查看我的问题的多个版本,但找不到我正在尝试做的事情的答案。

问题:
我有一个带有一堆十进制数字数据的 Pandas 数据框,这些数据是通过实验的多次迭代(每行)收集的,用于多种波长的光(每列)。这些波长间隔是列标题,由于我们机器的限制,波长/列之间的间隔目前是2.5。

我现在需要计算波长间隔为 0.1 而不是 2.5 时每行的值应为多少。这将要求我创建间距为 0.1 的新列标题(因此我当前的每个列之间有 24 个新列),然后在每个 0.1 步长处对每行中的值进行线性插值。

有人可以帮忙吗?我完全不知道如何做到这一点。

到目前为止我的收获:

# data_in = my original Panda dataframe with experiment data.
# wavelengths (column headers) go from 400 to 900 in 2.5nm intervals.
# I want 400 to 900 in 0.1 nm intervals.

# Create a copy dataframe for generating the interpolated columns, 
# copying the structure of the original file for the first 3 columns.
# (I need the first 3 columns intact for an unimportant reason)
data_interp = data_in[data_in.columns[0:3]].copy()

# Interpolate 400 to 900 nm in 0.1 nm steps for the column headers.
wave_array = np.linspace(400, 900, num=5000, endpoint=True)

# Import the interpolated numpy array as column headers in the new panda dataframe.
data_interp = pd.concat([data_interp,pd.DataFrame(columns=wave_array)])

# Use the pandas 'update' function to map any matching instances of columns and their data   
# from 'data_in' to 'data_interp' (ie, import all the 2.5 nm interval data from  
# the old dataframe to their proper place in the new dataframe).
data_interp.update(data_in)

现在我有一个新的 Panda 数据帧 (data_interp),其中包含我所有的原始 2.5 nm 间隔数据,以及 TON 的空列和 0.1 nm 间隔标题。

我需要用插值数据填充所有这些空单元格,这些插值数据是根据以 2.5 nm 间隔存在的数据计算得出的。

欢迎任何帮助,谢谢。

编辑 1:这是我的输入数据帧 (data_in) 和我的新插值数据帧 (data_interp) 的几张照片。

data_in:

data_interp:

编辑 2:小型化示例。

# Mini data.
data_mini = [[10, 13, 11], [15, 14, 15], [19, 18, 22]] 

# Convert to pandas dataframe
data_mini_pd = pd.DataFrame(data_mini, columns = [400, 402.5, 405])  

# Copy new dataframe based on original dataframe
data_mini_pd_interp = data_mini_pd[data_mini_pd.columns[0:0]].copy()

# Interpolate 400 to 405 nm in 0.1 nm steps for the column headers.
wave_array_mini = np.linspace(400, 405, num=50, endpoint=True)

# Round all numbers to 1 decimal place, to prevent float placeholder overflow
# when importing to panda column headers.
wave_array_mini_round = np.around(wave_array_mini, decimals=1)

# Import the interpolated numpy array as column headers in the new panda dataframe.
data_mini_pd_interp = pd.concat([data_mini_pd_interp,pd.DataFrame(columns=wave_array_mini_round)])

# Use the pandas 'update' function to map any matching instances of columns and their data from 'data_in' to 'data_interp' (ie, import all the 2.5 nm interval
# data from  the old dataframe to their proper place in the new dataframe).
data_mini_pd_interp.update(data_mini_pd)

【问题讨论】:

  • 您能否向我们提供一些示例数据(几行原始数据)并展示您目前得到的数据?
  • @SergeBallesta 我添加了指向我的两个数据帧的屏幕截图的链接。
  • 我们无法从图像中复制任何内容...您应该提供可复制的数据。顺便说一句,为什么数据框 column wise?使用 DateTimeIndex 标记行更为常见。
  • @SergeBallesta 好的,我已经包含了一个我正在使用的数据的迷你示例。我无法控制传入数据的格式——这就是我获取它的方式。正如您所说,数据由标记行的 DateTime 索引组织(我在显示期间切断了这些列,因为它包含一些敏感信息)。

标签: python pandas dataframe interpolation


【解决方案1】:

这个解决方案有点难看,但应该可以解决问题:

##generate data
nrows = 100
cols = [x/10.0 for x in range(0, 100, 25)]
data = {c: np.random.uniform(0, 1, nrows) for c in cols}

df = pd.DataFrame(data)

 interpolation_steps = 25 
 dfs = []
 #Iterate on each interpolation pair(start, end)
 for col_ind in range(0, len(cols)-1):
     ##Using list comparison to iterate on each row, performin np.linspace on relevant columns values and creating a dataframe based on these results(along with column names).
     inter_df = pd.DataFrame([np.linspace(x, y, interpolation_steps) for x, y in 
     zip(df.iloc[:, col_ind], df.iloc[:, col_ind + 1])],
            columns=[i/10 for i in range(int(df.columns[col_ind]*10), 
            int(df.columns[col_ind+1]*10), 1)])
     dfs.append(inter_df)

  ##Merging interpolated dataframes back together into one big dataframe
  full_df = pd.concat(dfs, axis=1)
  ##adding last column because interpolated without it
  last_col = df.columns[-1]
  full_df.loc[:, last_col] = df[last_col]
  print(full_df.head(3).T)

【讨论】:

  • 这看起来可能是我需要的。我正在吃一顿饭,当我回到我的办公桌时会看看这个。无论哪种方式,都感谢您抽出宝贵的时间来写这篇文章!
  • 现在我已经有更多时间回来查看。即使在我为正确的文件格式/列调整了一些东西之后,这也完全符合我的需要 - 谢谢!我来自 MATLAB,循环需要比 Python 更明确地编写(/笨拙?) - 压缩的速记仍然是我习惯的东西。如果您看到这一点并愿意花更多时间,我不介意解释您的“inter_df = ...”命令到底发生了什么。如果没有,我会继续努力阅读,无论如何谢谢!
【解决方案2】:

我会转置矩阵并欺骗(新)索引以使其成为 DatetimeIndex - 绝对值将偏离 1000 倍,但这对数据无关紧要。这样就可以以不同的频率重新采样数据帧。

之后,将索引转换回浮点数并再次转置以获得预期结果就足够了。

从你的data_mini_dp开始,可能是:

df = data_mini_pd.T.set_index(pd.to_datetime(
    (data_mini_pd.columns * 10).astype(int), format='%f')
                              ).resample('100000ns').interpolate()

df.index = df.index.strftime('%f').astype('float64')/1000

resul = df.T

给予:

   400.0  400.1  400.2  400.3  400.4  400.5  400.6  400.7  400.8  400.9  401.0  401.1  401.2  401.3  401.4  401.5  401.6  401.7  401.8  401.9  402.0  402.1  402.2  402.3  402.4  402.5  402.6  402.7  402.8  402.9  403.0  403.1  403.2  403.3  403.4  403.5  403.6  403.7  403.8  403.9  404.0  404.1  404.2  404.3  404.4  404.5  404.6  404.7  404.8  404.9  405.0
0   10.0  10.12  10.24  10.36  10.48   10.6  10.72  10.84  10.96  11.08   11.2  11.32  11.44  11.56  11.68   11.8  11.92  12.04  12.16  12.28   12.4  12.52  12.64  12.76  12.88   13.0  12.92  12.84  12.76  12.68   12.6  12.52  12.44  12.36  12.28   12.2  12.12  12.04  11.96  11.88   11.8  11.72  11.64  11.56  11.48   11.4  11.32  11.24  11.16  11.08   11.0
1   15.0  14.96  14.92  14.88  14.84   14.8  14.76  14.72  14.68  14.64   14.6  14.56  14.52  14.48  14.44   14.4  14.36  14.32  14.28  14.24   14.2  14.16  14.12  14.08  14.04   14.0  14.04  14.08  14.12  14.16   14.2  14.24  14.28  14.32  14.36   14.4  14.44  14.48  14.52  14.56   14.6  14.64  14.68  14.72  14.76   14.8  14.84  14.88  14.92  14.96   15.0
2   19.0  18.96  18.92  18.88  18.84   18.8  18.76  18.72  18.68  18.64   18.6  18.56  18.52  18.48  18.44   18.4  18.36  18.32  18.28  18.24   18.2  18.16  18.12  18.08  18.04   18.0  18.16  18.32  18.48  18.64   18.8  18.96  19.12  19.28  19.44   19.6  19.76  19.92  20.08  20.24   20.4  20.56  20.72  20.88  21.04   21.2  21.36  21.52  21.68  21.84   22.0

【讨论】:

  • 感谢您抽出宝贵时间。尽管我对 DateTime 转换持谨慎态度,但它肯定比其他解决方案更简洁。所有的提升都是由“data_mini_pd.resample(...”和“data_mini_pd.interpolate()”完成的吗?而且“.resample”需要一个 DateTime 戳才能工作而不是一个浮点数?我很惊讶它处理了所有没有明确指定行的数据,在哪些列之间插入,需要创建中间列的事实,等等。
猜你喜欢
  • 1970-01-01
  • 2020-02-05
  • 2019-10-20
  • 2023-02-16
  • 1970-01-01
  • 2020-07-22
  • 1970-01-01
  • 2016-10-24
  • 1970-01-01
相关资源
最近更新 更多