【问题标题】:Create Pandas DataFrames from Unique Values in one Column从一列中的唯一值创建 Pandas DataFrame
【发布时间】:2019-10-21 01:47:17
【问题描述】:

我有一个包含 1000 行的 Pandas 数据框。它的Names 列包含客户姓名及其记录。我想根据每个客户的唯一名称为每个客户创建单独的数据框。我将唯一名称放入列表中

customerNames = DataFrame['customer name'].unique().tolist() 这给出了以下数组

['Name1', 'Name2', 'Name3, 'Name4']

我通过捕获上面列表中的唯一名称并为每个名称创建数据框并将数据框分配给客户名称来尝试循环。所以例如当我写Name3时,它应该把Name3的数据作为一个单独的数据框

for x in customerNames:
    x = DataFrame.loc[DataFrame['customer name'] == x]
x

以上行仅返回 Name4 的数据帧作为数据帧结果,但跳过了其余部分。

我该如何解决这个问题?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    您当前的迭代每次运行时都会覆盖 x 两次:for 循环将客户名称分配给 x,然后您为其分配数据帧。

    为了以后能够按名称调用每个数据帧,请尝试将它们存储在字典中:

    df_dict = {name: df.loc[df['customer name'] == name] for name in customerNames}
    
    df_dict['Name3']
    

    【讨论】:

      【解决方案2】:

      要为列中的所有唯一值创建数据框,请创建 dict 的数据框,如下所示。

      • 创建一个dict,其中每个键都是来自所选列的唯一值,并且该值是一个数据框。
      • 像访问标准字典一样访问每个数据帧(例如df_names['Name1']
      • .groupby() 创建一个generator,可以解包。
        • k 是列中的唯一值,v 是与每个 k 关联的数据。

      带有for-loop.groupby

      df_names = dict()
      for k, v in df.groupby('customer name'):
          df_names[k] = v
      

      带有Python Dictionary Comprehension

      使用.groupby

      df_names = {k: v for (k, v) in df.groupby('customer name')}
      
      • 这来自与rafaelc 的对话,他指出使用.groupby.unique 更快。
        • 在列中有 6 个唯一值,.groupby 更快,104 毫秒与 392 毫秒相比
        • 在列中有 26 个唯一值时,.groupby 更快,为 147 毫秒,而 1.53 秒。
      • 使用 for-loop 比解析略快,特别是对于更独特的列值或大量行(例如 10M)。

      使用.unique:

      df_names = {name: df[df['customer name'] == name] for name in df['customer name'].unique()}
      

      测试

      • 以下数据用于测试
      import pandas as pd
      import string
      import random
      
      random.seed(365)
      
      # 6 unique values
      data = {'class': [random.choice(['1-5', '6-25', '26-100', '100-500', '500-1000', '>1000']) for _ in range(1000000)],
              'treatment': [random.choice(['Yes', 'No']) for _ in range(1000000)]}
      
      # 26 unique values
      data = {'class': [random.choice( list(string.ascii_lowercase)) for _ in range(1000000)],
              'treatment': [random.choice(['Yes', 'No']) for _ in range(1000000)]}
      
      df = pd.DataFrame(data)
      

      【讨论】:

        【解决方案3】:

        也许我误会了你,但是

        什么时候

        for x in customerNames:
            x = DataFrame.loc[DataFrame['customer name'] == x]
        x
        

        为最后一个列表条目提供正确的输出,因为您的输出超出了循环的缩进

        import pandas as pd
        
        customer_df = pd.DataFrame.from_items([('A', ['Jean', 'France']), ('B', ['James', 'USA'])],
                                orient='index', columns=['customer', 'country'])
        
        customer_list = ['James', 'Jean']
        
        for x in customer_list:
            x = customer_df.loc[customer_df['customer'] == x]
            print(x)
            print('now I could append the data to something new')
        

        你得到输出:

          customer country
        B    James     USA
        now I could append the data to something new
          customer country
        A     Jean  France
        now I could append the data to something new
        

        或者如果你不喜欢循环,你可以选择

        import pandas as pd
        
        customer_df = pd.DataFrame.from_items([('A', ['Jean', 'France']), ('B', ['James', 'USA']),('C', ['Hans', 'Germany'])],
                                orient='index', columns=['customer', 'country'])
        
        customer_list = ['James', 'Jean']
        
        
        print(customer_df[customer_df['customer'].isin(customer_list)])
        

        输出:

          customer country
        A     Jean  France
        B    James     USA
        

        df.isin 更好解释:How to implement 'in' and 'not in' for Pandas dataframe

        【讨论】:

          猜你喜欢
          • 2018-08-25
          • 1970-01-01
          • 2017-10-08
          • 1970-01-01
          • 1970-01-01
          • 2015-12-05
          • 1970-01-01
          • 2021-06-15
          • 2018-03-04
          相关资源
          最近更新 更多