如果数据帧中的行具有匹配的子字符串,则将值从一行添加到另一行

2024-06-03 06:18:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用一个图书发行商的例子来处理pandas中的数据帧

仓库生成.csv文件,将具有相同标题的书籍的已签名和未签名(由作者)副本视为不同的行,例如:

TITLE      //                      STOCK

A song of ice and fire     //       5

A song of ice and fire (signed)  //  1

但是,我希望每个标题都是一行,但有一个额外的列用于签名股票,例如:

TITLE            //                STOCK  //   SIGNED STOCK

A song of ice and fire      //       5       //     1

我已经成功地将CSV读入pandas数据帧,并添加了一个名为SIGNED STOCK的空白列,用零填充。我还清理了代码,去掉了空格和NaN 但是,我不知道如何在行中搜索带有子字符串(signed)的标题,然后将股票添加到相关标题的相关SIGNED STOCK列中。非常感谢您的帮助!:)

IBS_combined = pd.read_csv("IBS_21_05_19.csv",usecols=[3,12,21],encoding='latin-1')

IBS_combined.columns= ['Product', 'ISBN','Stock']

IBS_combined['Signed Stock']='0'

IBS_combined.replace(['Product'], np.nan, inplace=True)

IBS_combined.dropna(subset=['Product'], inplace=True)

Tags: andofcsv数据标题pandassongtitle
2条回答

您可以将数据帧拆分为两个分别具有有符号行和无符号行的df,然后合并结果。下面是一个例子(假设ISBN是识别一本书的唯一键,同一本书中有签名或无签名股票的条目不应超过1个):

  1. 设置包含ISBN的示例数据:

    • 1个有符号条目和1个无符号条目
    • 仅1份签署的库存条目
    • 仅1个未签名的库存条目

      str="""ISBN // TITLE // STOCK
      1 // A song of ice and fire // 5
      1 // A song of ice and fire (signed) // 1
      2 // another book // 10
      2 // another book (signed) // 2
      3 // 2nd book // 3
      4 // 3rd book (signed) // 1"""
      
      df = pd.read_csv(pd.io.common.StringIO(str), sep=' // ', engine='python')
      
  2. 根据下面的掩码m,将数据帧拆分为两个数据帧:

    • 数据框签名:df[m]
    • 数据框无符号:df[~m]

      m = df.TITLE.str.contains('\(signed\)')
      
  3. 格式化df_signed(将ISBN设置为索引,重命名列并从标题列中删除子字符串'(signed)':

    df_signed = df[m].set_index('ISBN')\
                     .rename(columns={'STOCK':'SIGNED_STOCK'}) \
                     .replace('\s*\(signed\)', '', regex=True)
    print(df_signed)
    #                       TITLE  SIGNED_STOCK
    #ISBN
    #1     A song of ice and fire             1
    #2               another book             2
    #4                   3rd book             1
    
  4. 设置df\u unsigned并使用DataFrame.combine_first()与df\u signed连接

    df_new = df[~m].set_index('ISBN') \
                   .combine_first(df_signed) \
                   .fillna(0, downcast='infer') \
                   .reset_index() 
    print(df_new)
    #   ISBN  SIGNED_STOCK  STOCK                   TITLE
    #0     1             1      5  A song of ice and fire
    #1     2             2     10            another book
    #2     3             0      3                2nd book
    #3     4             1      0                3rd book
    
  5. 重新排列列的顺序:

    cols = ['TITLE', 'ISBN', 'STOCK', 'SIGNED_STOCK']
    df_new = df_new[cols]
    

你可以这样做:

signed = []
for row in IBS_combined.iterrows():
    if row['TITLE'].find(your_string) != -1:
        signed.append(row['TITLE'].replace(your_string,''))

然后,您可以循环通过签名并添加金额

for item in signed:
    IBS_combined[IBS_combined['TITLE']==item]['SIGNED'] = IBS_combined[IBS_combined['TITLE']==item]['SIGNED'] +1

相关问题 更多 >