【问题标题】:How to subset and list a DataFrame using for loop in Python?如何在 Python 中使用 for 循环对 DataFrame 进行子集化和列出?
【发布时间】:2017-07-31 10:41:08
【问题描述】:

我有一个包含 3 列和 1,000 多行的 DataFrame,

df 
   day         product         order
2010-01-01    150ml Mask          9
2010-01-02    230ml Lotion       27
2010-01-03    600ml Shampoo      33

我想将每个产品子集如下,

 df_mask                 df_lotion            df_shampoo  
   day        order        day       order     day         order
2010-01-01      9       2010-01-02    27      2010-01-03    33   
2010-01-09      8       2010-01-05    30      2010-01-04    25
2010-01-11     13       2010-01-06    29      2010-01-06    46

我就是这么干的,

# Create a product list 
productName = df['product'].tolist()

# Subsetting
def subtable(df,productName):
    return (df[(df['product'] == productName)])

# Subsetting
df_mask = subtable(df, '150ml Mask')
df_lotion = subtable(df, '230ml Lotion')
df_shampoo = subtable(df, '230ml Shampoo')

由于数据框有许多不同的产品,有什么方法可以让我一次使用 for 循环获取所有子集。

【问题讨论】:

    标签: python pandas for-loop dataframe subset


    【解决方案1】:

    我认为您可以使用dict 存储所有DataFrames,它是由dict comprehensiongroupbysplit 创建的:

    producs = df['product'].str.split().str[-1]
    print (producs)
    0       Mask
    1     Lotion
    2    Shampoo
    Name: product, dtype: object
    
    dfs = {i:df.reset_index(drop=True) for i, df in df.groupby(producs)}
    print (dfs)
    {'Shampoo':           day        product  order
    0  2010-01-03  600ml Shampoo     33, 'Mask':           day     product  order
    0  2010-01-01  150ml Mask      9, 'Lotion':           day       product  order
    0  2010-01-02  230ml Lotion     27}
    
    print (dfs['Shampoo'])
              day        product  order
    0  2010-01-03  600ml Shampoo     33
    

    如果您需要删除列product,请使用子集[['day','order']]drop

    dfs = {i:df.reset_index(drop=True)[['day','order']] for i, df in df.groupby(producs)}
    #dfs = {i:df.reset_index(drop=True).drop('product', axis=1) for i, df in df.groupby(producs)}
    print (dfs)
    {'Shampoo':           day  order
    0  2010-01-03     33, 'Mask':           day  order
    0  2010-01-01      9, 'Lotion':           day  order
    0  2010-01-02     27}
    
    print (dfs['Shampoo'])
              day  order
    0  2010-01-03     33
    

    【讨论】:

      【解决方案2】:

      您可以为此使用groupby,这正是您所需要的:

      # show example data
      print(df)
      
           day           product             order
      0    2010-01-01    "150ml Mask"          9
      1    2010-01-02    "230ml Lotion"       27
      2    2010-01-03    "600ml Shampoo"      33
      3    2010-01-04    "250ml Mask"         12
      4    2010-01-05    "330ml Lotion"       24
      5    2010-01-06    "400ml Shampoo"      13
      
      # split product column and keep only product name
      df["product"] = df["product"].str.split(expand=True)[1]
      
      # groupby product
      products = df.groupby("product")
      
      # print product and corresponding product df
      for product, product_df in products:
          print(product)
          print(product_df)
      
      Lotion
                day product  order
      1  2010-01-02  Lotion     27
      4  2010-01-05  Lotion     24
      
      Mask
                day product  order
      0  2010-01-01    Mask      9
      3  2010-01-04    Mask     12
      
      Shampoo
                day  product  order
      2  2010-01-03  Shampoo     33
      5  2010-01-06  Shampoo     13
      

      为了单独访问每个子组,您可以使用与您的subtable 函数相对应的get_group

      mask_df = products.get_group("Mask")
      print(mask_df)
      
          day         product     order
      0   2010-01-01  Mask        9
      3   2010-01-04  Mask        12
      

      最后,要获取一个字典中的所有子数据帧,您可以循环 products 并删除产品列本身:

      df_dict = {product: product_df.drop("product", axis=1) 
                for product, product_df in products}
      print(df_dict["Mask"])
      
          day         order
      0   2010-01-01  9
      3   2010-01-04  12
      

      【讨论】:

      • 感谢您的回答。我试过df["product"] = df["product"].str.split(expand=True)[1],但有些产品名称没有组织,因为有些产品名称看起来像0.7OZ Mask UK 6。有没有其他方法可以解决这个问题?
      • @peggy 产品标签可能有哪些变化?提取产品名称完全取决于您的输入数据。但是,对于您在评论中给出的示例,df["product"].str.split(expand=True)[1] 应该成功地从0.7OZ Mask UK 6 中提取 Mask。或者你需要面具包括UK 6吗?
      • 是的。我需要 英国面具 6 。但我决定为每个产品分配一个特定的编号,以便于分类。除此之外,代码运行得很好。非常感谢!
      【解决方案3】:

      看看有没有帮助:

      dfs = {}
      for grp in df.groupby('product'):
          dfs[grp[0].split(' ')[1]] = grp[1] # split gives you the product name as key
      
      for key in dfs.keys():
          print dfs[key]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-26
        • 1970-01-01
        • 2015-06-20
        • 2021-02-05
        • 2020-03-22
        • 1970-01-01
        相关资源
        最近更新 更多