从一个列中的唯一值创建Pandas数据框架

4

我有一个包含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 的数据框作为结果,而忽略了其他内容。 如何解决这个问题?
3个回答

10

你当前的迭代每次运行都会两次覆盖 x:for 循环将客户名称分配给 x,然后你又将 dataframe 分配给它。

为了能够稍后按名称调用每个 dataframe,请尝试将它们存储在一个字典中:

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

df_dict['Name3']

9
为了创建一个包含某一列中所有唯一值的数据帧,可以按以下方式创建一个数据帧字典。
  • 创建一个 dict,其中每个键是选择的列中的唯一值,而值则是一个数据帧。
  • 像标准的字典一样访问字典中的每个数据帧(例如,df_names['Name1'])。
  • .groupby() 创建了一个生成器,它可以被解压。
    • k 是该列中的唯一值,v 是与每个 k 相关联的数据。

通过 for-loop.groupby 实现:

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

使用Python字典推导式

使用.groupby

df_names = {k: v for (k, v) in df.groupby('customer name')}
  • 这是从与 rafaelc 的对话中得出的结论,他指出使用.groupby.unique更快。
    • 在该列中有6个唯一值时,.groupby更快,为104毫秒,而.unique为392毫秒
    • 在该列中有26个唯一值时,.groupby更快,为147毫秒,而.unique为1.53秒。
  • 对于更多唯一的列值或大量行(例如10M),使用for-loop比理解稍微快一些。

使用.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)

0

也许我理解错了,但是

什么时候

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更好的解释在于:如何为Pandas dataframe实现'in'和'not in'


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接