替换行中的最后一个非NaN值

时间:2020-07-15 11:03:39

标签: python pandas numpy dataframe

我想用NaN值替换数据框中行中的所有最后一个非NaN。我的数据框中有300行和1068列。并且每行中都有用NaN填充的不同数量的有效值。 这是一行示例:

数据帧中的一行= import tensorflow as tf class CNNLSTMTimeseries(tf.keras.Model): def __init__(self, n_classes): super(CNNLSTMTimeseries, self).__init__() self.conv1 = tf.keras.layers.Conv1D(64, 7, padding='same', activation=None) self.bn1 = tf.keras.layers.BatchNormalization() self.conv2 = tf.keras.layers.Conv1D(64, 5, padding='same', activation=None) self.bn2 = tf.keras.layers.BatchNormalization() self.lstm = tf.keras.layers.LSTM(64, return_sequences=True) self.classifier = tf.keras.layers.Dense(n_classes, activation='softmax') def call(self, x): conv_x = tf.nn.relu(self.bn1(self.conv1(x))) conv_x = tf.nn.relu(self.bn2(self.conv2(conv_x))) lstm_x = self.lstm(x) x = tf.concat([conv_x, lstm_x], axis=-1) x = tf.reduce_mean(x, axis=1) # Average all timesteps return self.classifier(x) TIMESTEPS = 16 FEATURES = 32 model = CNNLSTMTimeseries(3) print(model(tf.random.uniform([1, TIMESTEPS, FEATURES])).shape) 输出= [1 2 3 NaN NaN NaN]

如何替换CSV文件中行中的最后一个非NaN值?

2 个答案:

答案 0 :(得分:1)

这是一个基于numpy的游戏:

import numpy as np
df = pd.DataFrame([[1, 2, 3, np.nan, np.nan, np.nan], [1, 2, 3, np.nan, np.nan, 2]])

您可以对值数组进行切片,并将其取反顺序,然后查找第一个有效值。然后获取索引,并使用np.put_along_axis将其设置为NaN s:

a = df.to_numpy()
m = a.shape[1]-1 - np.argmax(~np.isnan(a[:,::-1]), axis=1)
np.put_along_axis(a, m[:,None], np.nan, axis=1)
df[:] = a

print(df)

     0    1    2   3   4   5
0  1.0  2.0  NaN NaN NaN NaN
1  1.0  2.0  3.0 NaN NaN NaN

更多详细信息-

第一步是找到NaN的位置。并且由于我们需要最后一个有效值,因此我们应该从头开始。因此,切片可得到与列相反的数组,并使用np.isnan

np.isnan(a[:,::-1])
array([[ True,  True,  True, False, False, False],
       [False,  True,  True, False, False, False]])

现在我们可以使用False找到第一个np.argmax,即 last 有效值:

np.argmax(~np.isnan(a[:,::-1]), axis=1)
# array([3, 0], dtype=int64)

现在,通过将col长度减去上述长度,我们得到了实际的索引:

a.shape[1]-1 - np.argmax(~np.isnan(a[:,::-1]), axis=1)
# array([2, 5], dtype=int64)

现在我们可以在对应索引中将这些索引设置为NaN

np.put_along_axis(a, m[:,None], np.nan, axis=1)

答案 1 :(得分:0)

枚举列并在循环中检查值是否为NaN:

import pandas as pd
import numpy as np

df = pd.DataFrame([
[1, 2, 3, np.NaN, np.NaN, 2]
], columns=["a", "b", "c", "d", "e", "f"]
)

j = 0
for idx, c in enumerate(df.columns):
    if df[c].isna().any():
        while df.iloc[:, idx - j].isna().any():
            j += 1
        df.iloc[:, idx - j] = np.nan

print(df)

返回:

   a   b   c   d   e  f
0  1 NaN NaN NaN NaN  2

编辑:插入的NaN过多。将尝试修复它,否则删除答案..