如何在pandas表格的一列中计算逗号分隔的值数量?

7

I have the following code:

businessdata = ['Name of Location','Address','City','Zip Code','Website','Yelp',
'# Reviews', 'Yelp Rating Stars','BarRestStore','Category',
'Price Range','Alcohol','Ambience','Latitude','Longitude']

business = pd.read_table('FL_Yelp_Data_v2.csv', sep=',', header=1, names=businessdata)
print '\n\nBusiness\n'
print business[:6]

它会读取我的文件并创建一个可以操作的Panda表格。 我需要做的是统计每行“Category”变量中有多少个类别,并将此数字存储在一个名为“# Categories”的新列中。以下是目标列示例:
Category                                         
French                                               
Adult Entertainment , Lounges , Music Venues         
American (New) , Steakhouses                        
American (New) , Beer, Wine & Spirits , Gastropubs 
Chicken Wings , Sports Bars , American (New)         
Japanese

期望的输出:

Category                                        # Categories  
French                                               1           
Adult Entertainment , Lounges , Music Venues         3         
American (New) , Steakhouses                         2        
American (New) , Beer, Wine & Spirits , Gastropubs   4         
Chicken Wings , Sports Bars , American (New)         3         
Japanese                                             1        

编辑1:

原始输入= CSV文件。目标列:“类别” 我现在无法发布截图。 我认为要计算的值不是列表。

这是我的代码:

business = pd.read_table('FL_Yelp_Data_v2.csv', sep=',', header=1, names=businessdata, skip_blank_lines=True)
#business = pd.read_csv('FL_Yelp_Data_v2.csv')

business['Category'].str.split(',').apply(len)
#not sure where to declare the df part in the suggestions that use it.

print business[:6]

但是我一直收到以下错误提示:
TypeError: object of type 'float' has no len() 

编辑2:

我放弃了。感谢你们的所有帮助,但我将不得不想出其他办法。


我们的分类数据是以列表还是字符串的形式存储的,就像显示的那样? - EdChum
请发布原始输入数据和用于加载此数据的代码,正如您所看到的,您已经收到了许多答案,其中一些可能会回答您的问题。 - EdChum
到目前为止,问题仍未解决。 我已经在帖子中添加了一些信息。 我尝试执行 print type(business['Category']) is [所有类型的变量] 但总是返回 False。 - Danilo
9个回答

4
假设“Category”是一个列表,你可以使用 apply 函数(根据@EdChum的建议):
business['# Categories'] = business.Category.apply(len)

如果没有,你需要首先解析它并将其转换为列表。
df['Category'] = df.Category.map(lambda x: [i.strip() for i in x.split(",")])

您能展示一下这一列的精确样本输出吗(包括正确的引号)?
附言:@EdChum 感谢您的建议,我很感激。根据我测试的包含30k+行数据的文本数据样例,我相信列表推导式方法可能更快。
%%timeit
df.Category.str.strip().str.split(',').apply(len)
10 loops, best of 3: 44.8 ms per loop

%%timeit
df.Category.map(lambda x: [i.strip() for i in x.split(",")])
10 loops, best of 3: 28.4 ms per loop

即使考虑到 len 函数的调用:

%%timeit
df.Category.map(lambda x: len([i.strip() for i in x.split(",")]))
10 loops, best of 3: 30.3 ms per loop

你应该使用向量化的字符串方法:df.Category.str.strip().str.split(',').apply(len) - EdChum
抱歉我的知識不足,但這個“df”是什麼? - Danilo
我无法使用这些方法中的任何一个... 我一直收到“'float' object has no attribute 'split'” 的错误提示。 - Danilo
这表示你的“类别”列包含一些浮点数而不是字符串。 - Alexander
1
@Acoustic77,您是否可以提出一个新问题,并附上样本数据和期望的输出?您可以将其链接到此问题。谢谢。 - Alexander
显示剩余2条评论

2

这是有效的:

business['# Categories'] = business['Category'].apply(lambda x: len(x.split(',')))

如果您需要处理NA等情况,可以传递一个更详细的函数而不是lambda。

2
最好使用向量化的字符串拆分方法:business['Category'].str.split(',').apply(len) - EdChum
这是我根据你的建议得到的结果:`29 business = pd.read_csv('FL_Yelp_Data_v2.csv')
30 #business['# Category'] = business.Category.map(lambda x: [i.strip() for i in x.split(",")])
---> 31 business['# Categories'] = business['Category'].apply(lambda x: len(x.split(',')))
32
33 print type(business['Category']) is float AttributeError: 'float' object has no attribute 'split'`
- Danilo
当我回答时,显然我没有你的数据集。我假设“类别”列中的值是逗号分隔的字符串。 - Joe Germuska

2
business['Categories'] = business.Category.str.count(',')+1

1
虽然这段代码可能解决了问题,但是包括解释它如何以及为什么解决了问题将有助于提高您的帖子质量,并可能导致更多的赞。请记住,您正在回答未来读者的问题,而不仅仅是现在提问的人。请[编辑]您的答案以添加解释并指出适用的限制和假设。 - Dharman

0

我该如何实现函数vk1011? - Danilo
你可以用两种方法来实现:(1)使用内联分割和计数: business['number of categories'] = business['Categories'].apply(lambda x: len(x.split(',')))(2)定义一个函数并调用它: def split_and_count(string_to_split_and_count): split_up = string_to_split_and_count.split(',') num_categories = len(split_up) return num_categories在你的脚本中,你可以这样使用它:business['number of categories'] = business['Categories'].apply(lambda x: split_and_count(x)) - vk1011

0

你可以这样做...

for i in business['Category'].tolist():
    business.loc[i, '#Categories'] = len(i.split(","))

0

我曾经有过类似的疑问。我需要计算每行逗号分隔单词的数量,我是这样解决的:

data['Number_of_Categories'] = data['Category'].apply(lambda x : len(str(x).split(',')))

基本上,我首先将每一行转换为字符串,因为Python会将其识别为浮点数,然后执行'len'函数。希望这可以帮到你。


0
df['column_name'].apply(lambda n: \len(n.split(',')))

1
这是一个“仅代码”的答案。如果您能够在代码周围加上解释,提问者将更好地了解您试图实现什么以及它如何帮助他们解决问题。 - Andy

0

这可能是一个拼凑出来的解决方案,但我遇到了类似的问题,并使用类似于以下内容的东西进行了修复:

#Create an empty list to store your count in
numCategories=[]
#Create a loop to split each cell separately, then append to a list
i=0
while i <len(df):
#Switch out CategoriesColumnNumber in the below code for the correct column number
    temp_count = len(df.iloc[i,CategoriesColumnNumber].split(";"))
    numCategories.append(temp_count)
    i += 1
#Attach your newly generated list as a new column in your dataframe
df['#Categories'] = numCategories

这不是最美观的解决方案,但希望它能帮助一些刚开始学习的人!


0
df['#Categories'] = df['Category'].map(lambda x: len(x.split(",")) if isinstance(x, str) else 0)

我已经添加了错误处理 - 如果条件中的isinstance函数首先检查每个类别是否为字符串类型,然后才执行len函数,否则将返回0。

2
感谢您对Stack Overflow社区的贡献。这可能是一个正确的答案,但如果您能提供代码的额外解释,那将非常有帮助,这样开发人员就能理解您的思路。对于那些对语法不太熟悉或者正在努力理解概念的新手开发人员来说,这尤其有用。您是否可以编辑您的答案,以便为社区的利益提供更多细节? - undefined

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