如何用Python中的某些条件替换重复的数据框列值

时间:2020-11-11 15:21:25

标签: python pandas list dataframe csv

我有一个形状为(10x401)的数据框,其中重复的列具有相同的列名和值。其中一些具有空值,而另一些具有数字值。列名称未按排序顺序。下面是数据框的简短示例:

       ID#,       1,  1,  1,  1,  2,  2,  2,  2,  3,  3,  3,  3,.........,100,  100, 100, 100
   
        1,         ,   ,   ,   ,  3,  3,  3,  3,   ,   ,   ,   ,.........,  0,    0,   0,   0   
        2,        0,  0,  0,  0,   ,   ,   ,   , 10, 10, 10, 10,.........,   ,     ,    ,   
        3,        9,  9,  9,  9,  1,  1,  1,  1,  4,  4,  4,  4,.........,  1,    1,   1,   1
        .
        .
        .
       10,         ,   ,   ,   ,   ,   ,    ,  ,   ,   ,    ,   ,........., 6,    6,   6,   6

通过忽略空值,对于所有10行和400列(忽略ID列),我都需要将数字的第一次出现(从0到10)替换为1,并将其余所有值替换为-1。产生的数据框将如下所示:

       ID#,       1,  1,  1,  1,  2,  2,  2,  2,  3,  3,  3,  3,.........,100,  100, 100, 100
   
        1,         ,   ,   ,   ,  1, -1, -1, -1,   ,   ,   ,   ,.........,  1,   -1,   -1, -1   
        2,        1, -1, -1, -1,   ,   ,   ,   ,  1, -1, -1, -1,.........,   ,     ,     ,   
        3,        1, -1, -1, -1,  1, -1, -1, -1,  1, -1, -1, -1,.........,  1,   -1,   -1, -1
        .
        .
        .
       10,         ,   ,   ,   ,   ,   ,    ,  ,   ,   ,    ,   ,........., 1,   -1,   -1, -1

在此感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

首先,提供一些示例数据:

  const containerRef = useRef();
  const { current } = containerRef;

  useEffect(setLinksData, [current]);

return (
    <div ref={containerRef}>
      // your child elements...
    </div>
)
import pandas as pd

from io import StringIO

df_string = '''
ID;1;1;1;1;2;2;2;2;3;3;3;3
1;;;;;3;3;3;3;;;;
2;0;0;0;0;;;;;10;10;10;10
3;9;9;9;9;1;1;1;1;4;4;4;4
4;;;;;;;;;6;6;6;6
'''

df = pd.read_csv(StringIO(df_string), sep = ";", index_col="ID")

# Removing the automatically added .1/.2/... suffixes. You don't need that for your data.
df.columns = df.columns.str[0]

我建议转置DataFrame,因为使用pandas的矢量化方法更方便。多数情况下,只要指定 1 1 1 1 2 2 2 2 3 3 3 3 ID 1 NaN NaN NaN NaN 3.0 3.0 3.0 3.0 NaN NaN NaN NaN 2 0.0 0.0 0.0 0.0 NaN NaN NaN NaN 10.0 10.0 10.0 10.0 3 9.0 9.0 9.0 9.0 1.0 1.0 1.0 1.0 4.0 4.0 4.0 4.0 4 NaN NaN NaN NaN NaN NaN NaN NaN 6.0 6.0 6.0 6.0 ,就可以“水平”使用。

axis=1
df = df.T

首先,您需要知道所有包含值的单元格:

ID    1     2    3    4
1   NaN   0.0  9.0  NaN
1   NaN   0.0  9.0  NaN
1   NaN   0.0  9.0  NaN
1   NaN   0.0  9.0  NaN
2   3.0   NaN  1.0  NaN
2   3.0   NaN  1.0  NaN
2   3.0   NaN  1.0  NaN
2   3.0   NaN  1.0  NaN
3   NaN  10.0  4.0  6.0
3   NaN  10.0  4.0  6.0
3   NaN  10.0  4.0  6.0
3   NaN  10.0  4.0  6.0
ValueMask = ~df.isna()

第二,您需要知道新组的所有开始位置。将整个DataFrame向下移动一排并检查是否不相等会有所帮助。将其与您的ID 1 2 3 4 1 False True True False 1 False True True False 1 False True True False 1 False True True False 2 True False True False 2 True False True False 2 True False True False 2 True False True False 3 False True True True 3 False True True True 3 False True True True 3 False True True True 结合使用,您将获得起始单元格:

ValueMask
StartMask = (df.shift() != df) & ValueMask

现在,您可以将所有值单元格设置为ID 1 2 3 4 1 False True True False 1 False False False False 1 False False False False 1 False False False False 2 True False True False 2 False False False False 2 False False False False 2 False False False False 3 False True True True 3 False False False False 3 False False False False 3 False False False False ,然后将所有组开始的所有单元格设置为-1

1
df[ValueMask] = -1
df[StartMask] = 1

现在您可以随时将其转回:

ID    1    2    3    4
1   NaN  1.0  1.0  NaN
1   NaN -1.0 -1.0  NaN
1   NaN -1.0 -1.0  NaN
1   NaN -1.0 -1.0  NaN
2   1.0  NaN  1.0  NaN
2  -1.0  NaN -1.0  NaN
2  -1.0  NaN -1.0  NaN
2  -1.0  NaN -1.0  NaN
3   NaN  1.0  1.0  1.0
3   NaN -1.0 -1.0 -1.0
3   NaN -1.0 -1.0 -1.0
3   NaN -1.0 -1.0 -1.0
df = df.T