【问题标题】:Padding rows based on conditional根据条件填充行
【发布时间】:2020-09-06 22:30:23
【问题描述】:

我每行都有时间序列数据(以列作为时间步长),我想根据条件行值(即“填充量”)在每一行左右填充 0。这就是我所拥有的:

Padding amount     T1     T2     T3
   0               3      2.9    2.8
   1               2.9    2.8    2.7
   1               2.8    2.3    2.0
   2               4.4    3.3    2.3

这就是我想要制作的:

Padding amount     T1     T2     T3     T4     T5
   0               3      2.9    2.8    0      0    (--> padding = 0, so no change)
   1               0      2.9    2.8    2.7    0    (--> shifted one to the left)
   1               0      2.8    2.3    2.0    0
   2               0      0      4.4    3.3    2.3  (--> shifted two to the right)

我看到Keras 具有序列填充,但不确定考虑到所有行具有相同数量的条目,这将如何工作。我正在查看Shiftnp.roll,但我确信在某处已经存在解决方案。

【问题讨论】:

  • 这并不完全是一个骗子,但this 可以帮助你,除非你需要先创建缺少的列我猜
  • 为什么会有一个numpy标签?

标签: python pandas numpy keras


【解决方案1】:

在 numpy 中,您可以为要放置数组元素的位置构造一个索引数组。

假设你有

padding = np.array([0, 1, 1, 2])
data = np.array([[3.0, 2.9, 2.8],
                 [2.9, 2.8, 2.7],
                 [2.8, 2.3, 2.0],
                 [4.4, 3.3, 2.3]])
M, N = data.shape

输出数组是

output = np.zeros((M, N + padding.max()))

您可以对数据的去向进行索引:

rows = np.arange(M)[:, None]
cols = padding[:, None] + np.arange(N)

由于索引的形状广播到数据形状的形状,所以可以直接赋值输出:

output[rows, cols] = data

不确定这如何准确地应用于DataFrame,但您可以在对旧的values 进行操作后构建一个新的。或者,您可以直接在 pandas 中等效地实现所有这些操作。

【讨论】:

  • 如果你构造padding=df['Padding_amount'].to_numpy()data=df.filter(regex='T\d').to_numpy(),其中df是OP的数据框,那么放回output不太明显,但可以用df[[f'T{i}' for i in range(1, output.shape[1]+1)]] = pd.DataFrame(output, index=df.index)完成,无论如何你的方法真的不错
  • @Ben.T 谢谢。我不是真正的熊猫人,所以这很有帮助。
【解决方案2】:

这是一种方法,我已经使该过程在可以采取多少时间段/步骤方面非常灵活:

import pandas as pd

#data
d = {'Padding amount': [0, 1, 1, 2],
 'T1': [3, 2.9, 2.8, 4.4],
 'T2': [2.9, 2.7, 2.3, 3.3],
 'T3': [2.8, 2.7, 2.0, 2.3]}
#create DF
df = pd.DataFrame(data = d)
#get max padding amount
maxPadd = df['Padding amount'].max()
#list of time periods
timePeriodsCols = [c for c in df.columns.tolist() if 'T' in c]
#reverse list
reverseList = timePeriodsCols[::-1]
#number of periods
noOfPeriods = len(timePeriodsCols)

#create new needed columns
for i in range(noOfPeriods + 1, noOfPeriods + 1 + maxPadd):
    df['T' + str(i)] = ''

#loop over records
for i, row in df.iterrows():
    #get padding amount
    padAmount = df.at[i, 'Padding amount']
    #if zero then do nothing
    if padAmount == 0:
        continue
    #else: roll column value by padding amount and set old location to zero
    else:
        for col in reverseList:
            df.at[i, df.columns[df.columns.get_loc(col) + padAmount]] = df.at[i, df.columns[df.columns.get_loc(col)]]
            df.at[i, df.columns[df.columns.get_loc(col)]] = 0

print(df)

   Padding amount   T1   T2   T3   T4   T5
0               0  3.0  2.9  2.8          
1               1  0.0  2.9  2.7  2.7     
2               1  0.0  2.8  2.3    2     
3               2  0.0  0.0  4.4  3.3  2.3

【讨论】:

    猜你喜欢
    • 2021-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-28
    • 2021-08-28
    相关资源
    最近更新 更多