【问题标题】:Efficiently Remove all Zeroes from Pandas Dataframe有效地从 Pandas 数据框中删除所有零
【发布时间】:2021-06-18 07:58:10
【问题描述】:
train_subset.iloc[:10, :10]
1  0  7045    17    16.0    0.0    0.0   0.0   0.0  18.0
1  0  8907   137    48.0   42.0   53.0  32.0  35.0  30.0
1  0   917   167   193.0   88.0   48.0   0.0  24.0   0.0
1  0   203  5303  2073.0  153.0  108.0  97.0  73.0  89.0
1  0   198   817   198.0    0.0    0.0  88.0  93.0  70.0

我有一个名为 train 的数据集。我在这里打印了一小部分。

有没有一种有效的方法来删除数据集中的所有零,通过向左移动来更新列?例如,我想要的输出是......

请注意,我希望这仅从第 4 列开始触发。第一列、第二列和第三列是元数据,不应更改。

train_subset.iloc[:10, :10]
1  0  7045    17    16.0   18.0
1  0  8907   137    48.0   42.0   53.0  32.0  35.0  30.0
1  0   917   167   193.0   88.0   48.0  24.0 
1  0   203  5303  2073.0  153.0  108.0  97.0  73.0  89.0
1  0   198   817   198.0   88.0   93.0  70.0

基本上,您可以将每一行视为一个时间序列,我想忽略任何零。所以我只有在事件发生的时间点有读数,并且我已经删除了它们之间的所有零。

我可以弄清楚如何删除零并用 NA 或其他内容替换,但我不知道如何将每一行强制向左移动。

【问题讨论】:

  • "用 nan 替换零,然后删除所有条目为 nan 的行。然后用零替换 nan。"不过,我不想删除带有 NAN 条目的行。我只想删除 0 (NAN),然后将所有内容按列向左移动。

标签: python pandas data-cleaning


【解决方案1】:

np.argsort + boolean masking

s = df.iloc[:, 3:]
i = np.argsort(s.eq(0), axis=1)
df.iloc[:, 3:] = np.take_along_axis(s[s.ne(0)].values, i.values, axis=1)

说明

从fourth 列开始对给定数据帧的部分进行切片,然后将其与0 进行比较以创建布尔掩码。创建布尔掩码背后的想法是,当我们在下一步中对掩码进行排序时,False 值将首先出现,同时还保持相对顺序,这基本上提供了类似 shift 的行为。

>>> s.eq(0)

       3      4      5      6      7      8      9
0  False  False   True   True   True   True  False
1  False  False  False  False  False  False  False
2  False  False  False  False   True  False   True
3  False  False  False  False  False  False  False
4  False  False   True   True  False  False  False

现在在上面的掩码上使用np.argsort 来获取将sort 数据帧切片s 中的值的索引。

>>> np.argsort(s.eq(0), axis=1)

   3  4  5  6  7  8  9
0  0  1  6  2  3  4  5
1  0  1  2  3  4  5  6
2  0  1  2  3  5  4  6
3  0  1  2  3  4  5  6
4  0  1  4  5  6  2  3

然后使用np.take_along_axis 和上述索引对s 中的值进行排序,并将这些排序后的值分配给给定的数据框df。

>>> np.take_along_axis(s[s.ne(0)].values, i.values, axis=1)

array([[  17.,   16.,   18.,   nan,   nan,   nan,   nan],
       [ 137.,   48.,   42.,   53.,   32.,   35.,   30.],
       [ 167.,  193.,   88.,   48.,   24.,   nan,   nan],
       [5303., 2073.,  153.,  108.,   97.,   73.,   89.],
       [ 817.,  198.,   88.,   93.,   70.,   nan,   nan]])

结果

>>> df

   0  1     2       3       4      5      6     7     8     9
0  1  0  7045    17.0    16.0   18.0    NaN   NaN   NaN   NaN
1  1  0  8907   137.0    48.0   42.0   53.0  32.0  35.0  30.0
2  1  0   917   167.0   193.0   88.0   48.0  24.0   NaN   NaN
3  1  0   203  5303.0  2073.0  153.0  108.0  97.0  73.0  89.0
4  1  0   198   817.0   198.0   88.0   93.0  70.0   NaN   NaN

【讨论】:

    猜你喜欢
    • 2017-01-03
    • 2021-08-23
    • 2019-02-14
    • 1970-01-01
    • 2018-08-29
    • 2019-06-27
    • 2014-02-27
    • 1970-01-01
    相关资源
    最近更新 更多