代码之家  ›  专栏  ›  技术社区  ›  ByHala

如何编辑复制的值?

  •  0
  • ByHala  · 技术社区  · 3 年前

    我想更改副本的值。这是我的数据框架:

      sku
    FAT-001
    FAT-001
    FAT-001
    FAT-002
    FAT-002
    

    我预期的数据帧如下所示

      sku
    FAT-001 #don't want to change first value of duplicate 
    FAT-001-01
    FAT-001-02
    FAT-002
    FAT-002-01
    
    2 回复  |  直到 3 年前
        1
  •  2
  •   MoRe    3 年前
    df["number"] = df.groupby("sku").cumcount()
    df.apply(lambda x: x.sku + ("" if x.number == 0 else "-" + str(x.number).rjust(2,"0")), axis = 1)
    

    或者:

    df["number"] = "-" + df.groupby("sku").cumcount().astype(str).str.rjust(2, '0')
    df.number[df["number"].eq("-" + "0" * 2)] = ""
    df.sku + df.number 
    

    我的输出:

    0       FAT-001
    1    FAT-001-01
    2    FAT-001-02
    3       FAT-002
    4    FAT-002-01
    dtype: object
    

    说明:

    是什么 groupby ? 这是一个 sql-inspired 命令,根据每个独特的元素为您提供一些元素基础。。。例如:长度、最大值、列表或其他。。。

    df = pd.DataFrame([
        [1,2],
        [1,3],
        [1,4],
        [2,5],
        [2,6],
    ], columns=["id","number"])
    df.groupby("id").agg({"number": len})
    

    给你:

        number
    id  
    1   3
    2   2
    

    每个唯一元素的数量,或

    df.groupby("id").agg({"number": list})
    

    给你

        number
    id  
    1   [2, 3, 4]
    2   [5, 6]
    

    你可以试试 max min first ...

    使用 agg ,您可以为每个列指定所需内容。。。如果你有不止一个(除了 ),您可以为每个 column ...

    除了 阿格 ,还有其他的方法 goupped 数据帧:比如 cumcount ,它设置了每个 row 每人 group 我是认真的 index :

    df.groupby("sku").cumcount()
    

    输出:

    0    0
    1    1
    2    2
    3    0
    4    1
    

    你的第一次 FAT-001 收到 指数 :0,下一个:1。。。为了 FAT-002 ,首先再次获取索引0。。。

    所以,我们有两部分你想要的,现在。。。因此,我们必须找到一种方法,每一天都加入他们 一行 : axis:1 在里面 apply 每行的平均值

    所以,你有一个例外:你不想 指数 对于每组的每一行。。。因此,将其更改为“”,空:

    df.apply(lambda x: "" if x.number == 0 else str(x.number), axis = 1)
    

    :

    0     
    1    1
    2    2
    3     
    4    1
    dtype: object
    

    你的 0 3 行用于新组。。。

    接下来,你想要的格式是:01,02,。。。A. 0 对于每个索引。pandas有一种方法,可以将每个字符串转换为任意长度的字符串 char: rjust(期望长度,任意字符)

    工作原理:如果你称之为 rjust(2,"0") ,它不会改变 "22" 或者其他2字符,3字符。。。字符串,但是,如果字符串长度为1 1 将转换为 01 和(请注意,有一个名为 ljust 也:))

    df["number"] = df.groupby("sku").cumcount()
    df.apply(lambda x: "" if x.number == 0 else str(x.number).rjust(2,"0"), axis = 1)
    
    0      
    1    01
    2    02
    3      
    4    01
    dtype: object
    

    if 声明可以写成:

    if x.number == 0:
       return ""
    else:
        return "-" + str(x.number).rjust(2,"0")
    

    还有几点:

    1. 是什么 astype(str) :它将每个元素转换为字符串,工作方式如下 str(x) ,但对于每个元素。为什么?在前面加“-”并使用 rjust .
    2. 是什么 eq ? 它是 is-equal? 然后回来 True 对于每一行,如果值等于 False 否则
    3. 为什么? df.number[df["number"].eq("-" + "0" * 2)] = "" ? 因为我们将每个组的所有第一个元素转换为 ""
    4. 为什么? "-" + "0" * 2 ? 因为我们加上 "-" 而l1就在前一行,所以我们必须使用正确的值: "-00" .为什么 "0" * 2 ? 因为你可以用每一个数字 ljust length 比如10,也放在那里
        2
  •  0
  •   enke    3 年前

    与@MoRe的答案类似,使用 groupby.cumcount 创建团队;那你可以用 str.zfill 填补空白 mask 每组的第一个元素:

    groups = df.groupby('sku').cumcount()
    df['new'] = df['sku'] + ('-' + groups.astype('string').str.zfill(2)).mask(groups.eq(0), '')
    

    输出:

           sku         new
    0  FAT-001     FAT-001
    1  FAT-001  FAT-001-01
    2  FAT-001  FAT-001-02
    3  FAT-002     FAT-002
    4  FAT-002  FAT-002-01