这里有一些技巧可以避免过多的循环,从而获得更好的结果

图1 -标题图像。

​ 您曾经处理过需要使用列表的数据集吗?如果有,你就会明白这有多痛苦。如果没有,你最好做好准备。

​ 如果你仔细看,你会发现列表无处不在!下面是一些实际问题,您可能会遇到列表。

  • 音频或视频标签
  • 调查数据中的开放式问题
  • 参与创作作品的所有作者、艺术家、制作人等的名单

图2 -一个有趣的猫有关的视频的标签列表。

​ 我最近参与了多个项目,这些项目要求我分析这类数据。在经历了几个小时的痛苦摸索之后,我意识到必须在这里分享我的知识来帮助您节省时间。

​ 我将向您展示您可能会遇到的各种问题,并为它们提供实用的解决方案。

准备

​ 要遵循本教程,请下载用于所有示例的虚拟数据集。包括代码在内的所有资料都可以在这里找到。

​ 另外,请导入所有必要的库并加载数据格式。

import pandas as pd
import numpy as np
import matplotlib as pltfruits = pd.read_csv("fruits.csv", delimiter = ";")

图3 -数据集示例

列表值有什么问题呢?

​ 让我们直击要点:列表值打乱了您所知道的关于数据分析的一切。如果没有无尽的循环,甚至不能执行最简单的操作。让我给你们看一个简单的例子:

​ 对于示例数据集中的“age”列,我们可以轻松地使用value_counts()函数来计算观察到的年龄数据集的数量。

fruits["age"].value_counts()## OUTPUT ##
8     3
10    2
6     2
9     1
7     1
5     1

​ 如果我们想知道哪些水果被命名得最多呢?原则上,我们在“favorite_fruits”列中获得了所需的所有数据。然而,如果我们应用相同的函数,结果是没有帮助的。

fruits["favorite_fruits"].value_counts()## OUTPUT ##
["strawberry", "raspberry", "blueberry"]                      1
["mango", "pineapple", "orange"]                              1
["blueberry", "watermelon", "apple", "raspberry"]             1
["apple", "pear", "peach"]                                    1
["pear", "strawberry", "raspberry"]                           1
["banana", "maracuja", "watermelon", "apple", "pineapple"]    1
["peach", "strawberry", "apple", "blueberry"]                 1
[]                                                            1
["banana", "mango", "orange", "watermelon"]                   1
["watermelon", "apple", "blueberry", "pear", "strawberry"]    1

​ 这不起作用的原因是,Pandas不能直接访问列表中的每个元素。因此,它无法正确地应用value_counts()等函数。那么,我们该怎么做呢?我将在下面向您展示!

问题1:列表存储为字符串

​ 您经常会遇到的一个问题是,panda将以字符串的形式读取列表,而不是以列表的形式。

for i, l in enumerate(fruits["favorite_fruits"]):print("list",i,"is",type(l))## OUTPUT ##
list 0 is <class 'str'>
list 1 is <class 'str'>
list 2 is <class 'str'>
list 3 is <class 'str'>
list 4 is <class 'str'>
list 5 is <class 'str'>
list 6 is <class 'str'>
list 7 is <class 'str'>
list 8 is <class 'str'>
list 9 is <class 'str'>

​ 这意味着您甚至不能遍历列表来计算惟一值或频率。根据您的列表在dataframe格式化方式的,有一种简单的或复杂的解决方案。在任何情况下,您都可以使用我提供的代码。

你的字符串是这样的吗: “[‘strawberry’, ‘apple’, ‘orange’]”

​ 在这种情况下,有一个使用apply()eval()函数的快速方法。

fruits["favorite_fruits"] = fruits["favorite_fruits"].apply(eval)

你的字符串是这样的吗:“[strawberry, apple, orange]”?

​ 这个类型比较困难,eval()函数因为列表缺少内部引号而不能工作,以便将其识别为一个列表对象。快速而粗糙的解决方案是简单地向字符串添加引号,然后应用eval()。使用这个函数:

def clean_alt_list(list_):list_ = list_.replace(', ', '","')list_ = list_.replace('[', '["')list_ = list_.replace(']', '"]')return list_

​ 应用到dataframe时,请使用此伪代码:

df[col] = df[col].apply(clean_alt_list)

​ 注意,在这两种情况下,Pandas仍然会为系列分配一个“O”数据类型,这通常用于字符串。但是不要让这个迷惑了你。你可以使用检查实际的数据类型:

for i, l in enumerate(fruits[“favorite_fruits”]):print(“list”,i,”is”,type(l))## OUTPUT ##
list 0 is <class 'list'>
list 1 is <class 'list'>
list 2 is <class 'list'>
list 3 is <class 'list'>
list 4 is <class 'list'>
list 5 is <class 'list'>
list 6 is <class 'list'>
list 7 is <class 'list'>
list 8 is <class 'list'>
list 9 is <class 'list'>

问题2:获得特定的列表值

​ 在这第一步之后,我们的数据集最终被Pandas认可。但是,我们仍然不能使用标准函数,因为它们不是为列表设计的。

​ 至少我们现在可以使用循环。这个方法适合于小数据集,但会非常慢。例如,我如果分析高达999个标签,大约有500k音乐曲目的数据集。这意味着,内部循环将会有数亿次,这将花费数小时,并可能使我的计算机崩溃。我能给你展示一个更干净、更快的方法,在一分钟内完成此任务。然而,如果您真的想使用循环,下面是代码:

fruit_dict = {}
for i in fruits["favorite_fruits"]:for j in j:if j not in fruit_dict:fruit_dict[j] = 1else:fruit_dict[j] += 1

​ 我花了一段时间才弄清楚。如果我们将列表数据集化作为一个2D数组,然后将其维度从2减少到1,将允许我们再次应用经典的Pandas功能。为此,您可以使用这个函数:

def to_1D(series):return pd.Series([x for _list in series for x in _list])

​ 如果我们现在使用value_counts(),就会得到我们想要的结果。

to_1D(fruits[“favorite_fruits”]).value_counts()## OUTPUT ##
apple         5
blueberry     4
watermelon    4
strawberry    4
raspberry     3
pear          3
banana        2
pineapple     2
mango         2
peach         2
orange        2
maracuja      1

​ 要获得惟一的值,只需将.index()链接到上面的结果中提取它们。

​ 此时,我们可以生成第一个有意义的可视化。

fig, ax = plt.subplots(figsize = (14,4))
ax.bar(to_1D(fruits["favorite_fruits"]).value_counts().index,to_1D(fruits["favorite_fruits"]).value_counts().values)
ax.set_ylabel("Frequency", size = 12)
ax.set_title("Children's Favorite Fruits", size = 14)

图4 -显示所有水果的频率的条形图。

问题3:针对有唯一值的单独列

​ 如果您对我们之前得到的结果感到满意,就到此为止吧。但是,您的研究目标可能需要更深层次的分析。也许您希望将所有列表元素相互关联以计算相似度得分。比如吃香蕉的孩子也喜欢芒果吗?或者你想知道哪些水果是大多数孩子最喜欢的水果。这些问题只能通过更深层次的分析才能得到答案。

​ 为此,我将介绍两种有用的方法。它们的复杂性不同。

方法一

​ 这是我偶然发现的一个非常简单快速的方法。而且它非常有用!您只需要一行代码。

fruits_expanded_v1 = fruits["favorite_fruits"].apply(pd.Series)

图5 -使用方法1的水果列表的扩展版本

​ 正如您所看到的,这单独生成了一个dataframe,每个列表都分为单个元素。有了这个方法,您将总是得到一个具有一个(n,len(lonsig_list))dataframe。在这种情况下,10个孩子中有两个叫了5个最喜欢的水果,结果是一个10x5dataframe

​ 通过这个,我们就可以知道哪些水果是人们最喜欢的水果。

fruits_expanded_v1.iloc[:,0].value_counts(normalize = True)## OUTPUT ##
banana        0.222222 pear          0.111111 watermelon    0.111111 blueberry     0.111111 strawberry    0.111111 apple         0.111111 peach         0.111111 mango         0.111111

​ 我们可以看到香蕉是孩子们最喜欢的水果。

​ 或者,我们可以以单个水果为目标,找出它们在列表的每个位置被命名的次数。这是我写的函数:

def get_rankings(item, df):# Empty dict for resultsitem_count_dict = {}# For every tag in dffor i in range(df.shape[1]):# Calculate % of cases that tagged the itemval_counts = df.iloc[:,i].value_counts(normalize = True)if item in val_counts.index:item_counts = val_counts[item]else:item_counts = 0# Add score to dictitem_count_dict["tag_{}".format(i)] = item_countsreturn item_count_dict

​ 如果我们应用它,我们得到:

get_rankings(item = "apple", df = fruits_expanded_v1)## OUTPUT ##
{'tag_0': 0.1111111111111111,  'tag_1': 0.1111111111111111,  'tag_2': 0.2222222222222222,  'tag_3': 0.2,  'tag_4': 0}

​ 正如您所看到的,我们可以用这种方法进行大量的基于rpc的分析。然而,这种方法几乎没有其他用处。因为列不代表一个标记,而是一个级别,大多数在标签上的操作不能正确地完成。例如,计算香蕉和桃子之间的相关性是不可能的,我们从方法1得到了dataframe。如果这是你的研究目标,使用下一种方法。

方法二

​ 这种方法更加复杂,需要更多的空间。其思想是,我们创建一个dataframe,其中的行与以前相同,但每个水果都被分配了自己的列。如果只有孩子#2命名为banana,那么banana列在第2行将具有“True”值,而在其他地方将具有“False”值(参见图6)。我写了一个函数来执行这个操作。它依赖于循环,这意味着它将花费大量时间处理大型数据集。然而,在我所尝试的所有方法中,这是最有效的方法。

def boolean_df(item_lists, unique_items):# Create empty dictbool_dict = {}# Loop through all the tagsfor i, item in enumerate(unique_items):# Apply boolean maskbool_dict[item] = item_lists.apply(lambda x: item in x)# Return the results as a dataframereturn pd.DataFrame(bool_dict)

​ 如果我们现在应用这个函数

fruits_bool = boolean_df(fruits[“favorite_fruits”], unique_items.keys())

​ 我们得到这个表格:

图6 - 布尔表格。

​ 从这里,我们可以很容易地计算相关性。请注意,“相关性”并不是真正正确的术语,因为我们使用的不是度量或序数数据,而是二进制数据。

​ 同样,有多种方法来关联这些水果。一个直接的方法是皮尔逊相关系数,它也可以用于二进制数据。Pandas对此有一个内置函数。

fruits_corr = fruits_bool.corr(method = "pearson")

图7 -皮尔逊相关数据图

​ 另一种方法是简单地数一种水果和其他水果一起被命名的次数。这可以用矩阵乘法来解决。为此,我们需要将布尔型1转换为整数。

fruits_int = fruits_bool.astype(int)

​ 然后,我们可以计算频率。

fruits_freq_mat = np.dot(fruits_int.T, fruits_int)
## OUTPUT ##
array([[5, 3, 3, 2, 2, 1, 1, 1, 0, 2, 0, 1],[3, 4, 2, 1, 1, 1, 1, 2, 1, 0, 1, 1],[3, 2, 4, 3, 1, 2, 0, 0, 0, 1, 0, 0],[2, 1, 3, 4, 2, 2, 0, 0, 0, 1, 0, 0],[2, 1, 1, 2, 3, 1, 0, 0, 0, 1, 0, 0],[1, 1, 2, 2, 1, 3, 0, 0, 0, 0, 0, 0],[1, 1, 0, 0, 0, 0, 2, 1, 1, 0, 1, 1],[1, 2, 0, 0, 0, 0, 1, 2, 1, 0, 1, 1],[0, 1, 0, 0, 0, 0, 1, 1, 2, 0, 2, 0],[2, 0, 1, 1, 1, 0, 0, 0, 0, 2, 0, 0],[0, 1, 0, 0, 0, 0, 1, 1, 2, 0, 2, 0],[1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1]])

​ 现在我们需要做的就是添加标签并将其转换为dataframe

fruits_freq = pd.DataFrame(fruits_freq_mat, columns = unique_items.keys(), index = unique_items.keys())

图8 -频率数据表。

​ 如果你正在寻找一个漂亮的可视化方式,你可以创建一个seaborn库热图。

import seaborn as snfig, ax = plt.subplots(figsize = (9,5))
sn.heatmap(fruits_freq, cmap = "Blues")
plt.xticks(rotation=50)
plt.savefig("heatmap.png", dpi = 300)

图9 -热图。

​ 利用皮尔逊矩阵,我们可以很容易地建立一个水果推荐系统。例如,如果你输入你喜欢香蕉,它会推荐你吃西番莲,因为这两者的相关性最高(0.67)。您会对这种简单的方法的强大程度感到惊讶。我已经成功地用过很多次了。如果您想对频率 dataframe做类似的事情,您需要首先对数据进行规范化。然而,这是另一篇文章的主题。

​ 我希望这个指南对你有用,可以节省您的时间。谢谢大家的阅读!

作者:Max Hilsdorf

deephub翻译组:孟翔杰

Pandas的列表值处理技巧,避免过多循环加快处理速度相关推荐

  1. 生成新的dataframe_Python之Pandas使用系列(九):DataFrame中列操作的技巧

    介绍 本文将讨论使用iloc处理具有大量列的数据集的一些技巧和捷径.即使您有使用iloc的经验,也应该学习一些有用的技巧来加快自己的分析速度,并避免在代码中键入很多列名. 为什么我们关心选择列? 在许 ...

  2. 熊猫数据集_处理熊猫数据框中的列表值

    熊猫数据集 Have you ever dealt with a dataset that required you to work with list values? If so, you will ...

  3. python缺失值填充均值法_pandas 使用均值填充缺失值列的小技巧分享

    pd.DataFrame中通常含有许多特征,有时候需要对每个含有缺失值的列,都用均值进行填充,代码实现可以这样: for column in list(df.columns[df.isnull().s ...

  4. python pandas dataframe 列 转换为离散值

    python pandas dataframe 列 转换为离散值 import pandas as pd import numpy as np df1 = pd.DataFrame({'日期': [' ...

  5. python分组求和_Python学习笔记之pandas索引列、过滤、分组、求和功能示例

    本文实例讲述了Python学习笔记之pandas索引列.过滤.分组.求和功能.分享给大家供大家参考,具体如下: 前面我们已经把519961(基金编码)这种基金的历史净值明细表html内容抓取到了本地, ...

  6. python dataframe取一列_python - 从pandas DataFrame列标题中获取列表

    python - 从pandas DataFrame列标题中获取列表 我想从pandas DataFrame中获取列标题列表. DataFrame将来自用户输入,因此我不知道将会有多少列或将调用它们. ...

  7. python对excel表统计视频教程_Python实现对excel文件列表值进行统计的方法

    本文实例讲述了Python实现对excel文件列表值进行统计的方法.分享给大家供大家参考.具体如下: #!/usr/bin/env python #coding=gbk #此PY用来统计一个execl ...

  8. 用python编excel统计表_Python实现对excel文件列表值进行统计的方法

    本文实例讲述了Python实现对excel文件列表值进行统计的方法.分享给大家供大家参考.具体如下: #!/usr/bin/env python #coding=gbk #此PY用来统计一个execl ...

  9. python获取列表长度方法_python - 在Pandas df列中获取有关列表长度(平均长度,最大长度等)的统计信息的大多数pandas-onic方法 - 堆栈内存溢出...

    我想获取有关pandas df列中列表长度的统计信息,例如平均长度,最低,最高,标准差等. 例: import pandas as pd dfp = pd.DataFrame( {'trial_num ...

  10. python批量分析表格_Python统计分析execl文件列表值的方法

    用Python统计分析execl文件列表值的方法,采用python批量统计分析Excel表格数据工具代码编写示例.Python实现文件操方法有很多,python excel处理数据简洁方便. 下边关于 ...

最新文章

  1. python的难点在哪里_自己写的Python答案,不知道错在哪儿希望能被告知问题在哪儿和答案...
  2. RDKit | 通过评估合成难度(SA Score)筛选化合物
  3. 推特800赞:图网络论文实现大合集,70多篇分门别类,从未如此全面 | 已过1k星...
  4. np.random.seed的有效期及固定的种子会有固定的顺序
  5. Tmux: 打造精致与实用并存的终端
  6. sublime text3 之 ctags
  7. Gitbook 常用命令
  8. 5.支付平台架构:业务、规划、设计与实现 --- 账务系统
  9. 学校校园无盘教学系统
  10. NoSQL数据库——Hbase
  11. 最小生成树MST详解
  12. ODAC的tnsnames.ora文件
  13. 读书笔记-计算机视觉
  14. Elasticsearch入门 - 简单上手
  15. Gabor滤波器详解
  16. 顺丰快递 : 请收下 MySQL 灵魂十连
  17. python和anaconda安装顺序_Anaconda详细安装步骤图文教程
  18. linux创建磁盘的命令,linux中创建磁盘分区的命令是什么
  19. 技术类编程题汇总 C++ 刷题记录
  20. 2021 年全国职业院校技能大赛 网络搭建与应用赛项

热门文章

  1. 关于网站建设的主要流程和步骤(小白指南)
  2. user-modify
  3. HCIP 安全资料下载 肖哥视频
  4. 深度剖析mongos连接池
  5. 恒指2.25日预测及操作建议
  6. 影响力最大化 CELF 成本效益延迟转发算法
  7. CDA学习之Pandas - 十分钟搞定Pandas / Pandas秘籍
  8. SD--定价过程的16个字段的作用说明
  9. matlab仿真没有synchr,Synchro交通仿真系统分析及应用
  10. 50个程序员必须知道的网站,你知道么