Python 点模拟器
砸,还是不砸?
背景
计算机是检验统计和战略之间相互作用的理想工具。这是因为虽然战略问题往往是理论性的,但它们也意味着会对现实世界产生影响,而这些影响会通过统计结果反映出来。在许多情况下,统计结果太难手工研究,所以更容易做一个【蒙特卡洛模拟】,这是几个随机试验,试图梳理出模式。
扑克是一种极其复杂的游戏,两个人之间可能有超过十万亿手牌。这意味着目前的计算机远没有足够的能力来“解决”扑克,所以他们不得不经常使用巧妙的蒙特卡罗方法。我决定从简单一点开始,试着为 21 点做这件事。
特别感谢赔率向导,我用它的图表来设计我的策略函数。用于这个项目的代码在我的 Github 上,因为它太长了,不能粘贴在这里。
二十一点的规则
21 点是一种玩家与赌场对抗的游戏。玩家和赌场都试图得到不超过 21 的尽可能多的牌。过了 21 就意味着自动输了。如果玩家和赌场都过 21,赌场赢。然而,玩家可以在做出决定之前看到赌场的一张牌,而赌场的行为独立于玩家的牌,通常持续到其得分达到 17。
每张数字牌(2-10)都值它的数字,一张 ace 值 1 或 11,一张 face 牌值 10。请注意,这意味着实际上 10(10,J,Q,K)是其他牌的 4 倍。还有各种其他的警告,比如 21 点奖金、分成和双倍,你可以在这个[网站](http://Blackjack Rules - Learn How to Play 21 - [Tips & Best Practices] https://www.blackjack.org/blackjack-rules/)上读到。
Various blackjack outcomes and their associated results
项目概述
这个项目有三个阶段:
- 创建一个功能,为您提供战略性的 21 点建议,例如,是否击中,留等。
- 使用上述策略制作一个 21 点模拟器来模拟 21 点的一手牌
- 多次运行模拟以汇总结果并运行实验
第一阶段:战略
21 点是一个已经研究得相当多的游戏,互联网上有各种各样的地方有完美的策略,被称为’基本 21 点策略’。在你制定退休计划之前,请注意,即使你玩的是“完美的”21 点,与赌场相比,你的亏损额也很小(大约 0.5%),但只是比玩不完美 21 点的人输得慢。这些信息通常显示在网格状的图表中。下面是我在这个项目中使用的图的一个片段:
如果我的牌加起来是 12,而庄家有一张 7,则图表显示我应该“打”,即多拿一张牌。但是,如果庄家有 5,我应该“留下”,即放弃,并希望庄家“破产”(得分高于 21)。我把图表的每一个建议都编码进了一个函数,BlackJackStrategy。
阶段 2:模拟
尝试模拟 21 点的每一手牌是这个项目中最具挑战性的部分。我首先随机创建了一副牌,上面有所有的数字,以及四倍多的十。然后,使用随机数生成器,我给玩家发了两张牌,给庄家发了一张牌,并使用基本的 21 点策略来决定玩家将如何行动,并使用 21 点规则来决定结果。这些都在函数“21 点手牌结果”中。
注意:我使用的模拟假设有无限多副牌,因为赌场通常使用 6-8 副牌,这不会对结果产生太大影响。我将“分裂”的结果模拟成两只手,这允许我递归地处理分裂。这将减少方差一点点,但数量可以忽略不计。
阶段 3:重复模拟和实验
重复模拟是这个项目中最容易的部分,只要重复我的 21 点纸牌游戏就可以了。我的第一个实验是看看 21 点中的“赌场优势”是什么,这是你每赌 100 美元预计会输掉的钱数。我通过模拟一百万手牌尝试了几次,发现你会损失 10 到 40 美分。
实验一:翻倍 7 vs 庄家 6
在基本的 21 点策略图上,它说击中 7 对庄家的 6。如果我们加倍会怎么样?我在我的单手 21 点模拟器中添加了一个“硬编码”输入,它允许你对玩家的第一个动作进行硬编码,然后假设玩家在剩下的时间里遵循基本 21 点的建议。我首先运行了 100,000 次模拟,玩家下注 1 美元,拿着 3 和 4 与庄家的 6 进行比较,玩家赚了大约 2,000 美元。然而,当我运行 100,000 个 double 硬编码的模拟时,这变成了 15,000 美元的损失。这意味着,将 a 7 和 a 6 翻倍的决定花费了玩家 100,000 美元的赌注中的 17,000 美元,平均为他们赌注的 17%!
实验 2:拆分两个 10s vs 庄家 6
“千万不要拆 10”是 21 点的一条著名建议。让我们来评估一下,如果你拿着两张 10 和庄家拿着一张 6(这对庄家来说是最差的牌)分牌会发生什么。当我们在不拆分的情况下运行 100,000 次模拟时,玩家可以赚大约 70,000 美元。然而,当我们硬编码“分割”时,玩家只能获得 60,000 美元。虽然有两张 10 对一张 6 仍然非常有利可图,但玩家要花 10%的赌注来分割 10。
结论
可以通过改变硬编码来测试基本 21 点策略的每个方面,看看哪种方法在模拟中效果最好。编码和测试非常有趣,我期待在研究其他策略问题时应用类似的方法。
Python 代码:从假设检验到商业案例的在线实验
在线实验设计框架:
- 决定 KPI、护栏(主要指标、次要指标)
- 设计:第一类,第二类误差,样本量/持续时间,你的 H0 和 H1 是什么
- 设置实验(RTC,随机化算法)
- 衡量和比较(健全性检查、新颖性效果)
- 建议行动
这里我们关注第二步:实验设计和第四步:测量和比较。
理解 I 型、II 型误差、FPR、FNR、α、β的定义及其各自的数学公式非常关键。因为这些知识有助于建立理解和应用 p 值和功率的坚实基础。但是,文章不会深入表达那些术语和相关的统计知识(那不是这里的核心话题)。
对于非统计背景受众,p 值控制测试中检测到的提升/差异是否由随机机会引起,换句话说,两组之间没有提升/差异;功率控制看到测试中检测到的升力/差异为真(升力/差异)的概率,换句话说就是不要错过‘转出变化’的机会。
在步骤 2 和 3 中,我们需要选择:使用哪种假设检验?
首先让我们简单解释一下什么是 Z,T,F 测试以及什么时候使用它。在线实验 ab 检验中,最常见的情况是应用两样本假设检验
z,T 分布用来回答:两个样本来自同一个总体的概率有多大。回忆 t 分布有较厚的尾部。最终,越来越多的样本 t 分布将转化为 Z 分布
f 分布用于回答:两个样本来自具有相同方差的总体的概率是多少?通常,我们想知道三个或更多样本来自同一总体的概率是多少
卡方分布卡方拟合优度测试确定样本数据是否与总体匹配。独立性的卡方检验比较列联表中的两个变量,看它们是否相关。在更一般的意义上,它测试分类变量的分布是否彼此不同:
我们来编码吧!
通过 Z 检验的两个比例点估计
零假设(H0):两组均值是不同的——双边的
零假设(H0): u0 > u1 或 u0< u2 — one sided
Use case: Ran a fair AB test, control group got 486 clicks out of 5000 impression vs experiment group got 527 clicks out of 5000 impression. Could we say experiment group won the test? Given statistical significance as 0.95
In the result, p-value= 0.1742 >α= 0.05,我们未能拒绝 H0,这意味着从实验组观察到的高 CTR 是由于随机机会。对营销团队/产品团队的建议是不要推出这一新计划/变化。
通过点估计、带测试用例的 Z 检验确定样本大小
用例:根据转换率(CVR)计算样本量
假设:基线转换率=10%,CVR 提升 10%,显著水平=95%,功率=80%
我们需要每组至少 14744 次点击,这相当于 1.85 周,平均每周流量为 16k 次点击。在这个例子中,两周是一个很好的实验持续时间。
如果我的流量非常大(通常这对于许多公司来说并不常见,除了像脸书或谷歌这样的大型科技公司),并且能够达到 5 天的样本量,该怎么办?1.仍然运行至少 7 天,以捕捉每周趋势 2。给控制组分配更多的流量,不要浪费你的流量。
**“艺术作品在此”😗*在 1 .足够的力量(不要错过机会/察觉不到改进)2 .中寻找平衡或取舍。所需的最小样本量(交通量)3。有效尺寸(如果度量增加/减少多少,值得进行测试)-最小可检测差异
假设 alpha =0.05,幂= 0.8,让我们检查当改变有效大小时,样本大小如何变化
输出:
独立双样本 T 检验
对于两面派;H0 认为;两个集团的手段是不同的
对于一边倒:H0: u0 > u1 或 u0 < u2
Given Alpha= 0.05
Output:
We fail to reject null hypothesis with alpha=0.05
Sample size via point estimate, t test
It’s very similar to Z test (which we expressed a lot above) when using t test. Then let’s just code.
Chi-Square Test
Null hypothesis: no difference between two groups
用例:AA 测试—健全性检查:这两个组的观众是否相同。不均匀随机化?
示例:营销团队希望提高 CVR(通常营销团队更关心 CAC、RPU 或其他货币指标。这里用 CVR 来展示快速计算)通过测试一个新的关键字竞价算法。在推出 A/B 测试之前,需要进行 AA 测试,以确保两组的观众在 CVR 方面是相同的。
以下是在 AA 测试中要测试的假设:
H₀:两组的转换率是一样的
H₁:两组间的转换率不同
方法一:使用比例测试
可以使用比例检验,因为卡方分布是正态分布的平方
。在这种情况下(具有双侧替代的双样本情况),下面的卡方检验产生与比例 Z 检验相同的值。
输出:
我们无法拒绝 p 值= 0.175 >α= 0.05 的零假设
方法二:使用列联表——传统方法
输出:
这里我们得到了与比例测试相同的结果(p 值=0.174)。
方差分析检验和 f 分布
ANOVA 检验可用于测量这些平均值之间的统计显著性差异,进而测量其总体平均值之间的差异。
单向方差分析
- 无效假设:组均值相等(组均值无变化)
- 替代假设:至少一组均值与其他组不同
例如,一家公司的营销团队可能想要回答,如果五个州的销售业绩相同。用统计学的语言来表述这个问题。我们希望衡量不同州的销售额之间是否有任何差异,将销售额作为 KPI 进行评估。
任何假设检验的第一步都是将问题转化为无效假设和替代假设:
- H 0 : 组间均值相同
- 至少,一组的平均值是不同的
要执行此测试,我们必须根据所选的显著性水平或 p 值(通常为 0.05)和自由度,计算 f 检验统计值,并将其与 f 分布表中的临界值进行比较。
我们有了所有五个州(加利福尼亚州、纽约州、德克萨斯州、弗吉尼亚州和伊利诺伊州)的销售数据,然后让我们编码。
我们不能拒绝 H0,因为 p 值= 0.82 >α= 0.05。下一步是进行成对 t 检验,以发现哪些州在销售业绩方面与其他州不同。
双向方差分析
双向 f 检验:双向 f 检验是单向 f 检验的扩展,当我们有两个自变量和两个以上的组时使用。双向 f 检验不能说明哪个变量是主导变量。如果我们需要检查个体的显著性,那么就需要进行事后检验。
小样本量(低流量)补救措施
- 非参数统计检验
- 重采样—引导
- 找到与 KPI 高度相关的早期指标
1.非参数统计显著性检验—无分布
H0:两组,同分布
曼-惠特尼 U /威尔科克森-曼-惠特尼检验
独立双样本 t 检验的替代方法,数据类型:二进制。CVR 中心
输出:
2。重采样—助推器
赞成:没有正态假设(当样本量很小时,大多数情况下无效)
缺点:计算成本高。数据质量也很重要。
我曾经使用“scikit-learn”中的“重采样”包。然后我找到了这个为在线实验设计开发的 Python API,它使用起来非常直观。
Example is from bootstrapped library. Copyright 2016-present, Facebook, Inc. All rights reserved.
输出:
Example is from bootstrapped library. Copyright 2016-present, Facebook, Inc. All rights reserved.
让我们检查一下手段。
输出:
如示例所示,这是一个非常有用的库,并且易于应用。有关更多应用和详情,请查看以下链接:
bootstrapped 是一个 Python 库,允许您根据数据构建置信区间。这在各种场合都很有用…
pypi.org](https://pypi.org/project/bootstrapped/)
即使 AB 测试没有告诉你“为什么会发生”——真正的因果关系,它仍然是一个非常强大的工具,应用统计技术来改善用户体验,让客户更开心等等。我相信,在应用统计数据时,总有一种“艺术作品”可以在技术和工程之间找到平衡,推动收入增长(长期或短期)以及客户/用户的满意度。
使用熊猫数据帧、Spark 数据帧和考拉数据帧的 Python 数据预处理
为 Python 中的机器学习准备数据
随着在数据预处理、数据分析和机器学习中的广泛使用,Pandas 与 Numpy、Scikit-Learn 和 Matplotlib 一起成为 Python 中事实上的数据科学栈。
然而,Pandas 的主要限制之一是 Pandas 是为可以在单台机器上处理的小数据集设计的,因此它不能很好地扩展到大数据。相反,Apache spark 是为大数据设计的,但它有一个非常不同的 API,也缺乏 Pandas 中许多易于使用的数据争论和可视化功能。最近宣布了一个新的开源考拉,它通过增强 PySpark 的 DataFrame API 使其与 pandas DataFrame API 兼容,弥合了 Pandas DataFrame 和 Spark DataFrame 之间的差距。
在这篇文章中,类似于熊猫数据帧和 Spark 数据帧之间的比较,我使用一个公共数据集sample _ stocks . CSV来评估和比较熊猫、Spark 和考拉数据帧在机器学习的典型数据预处理步骤中的基本功能,包括:
- 加载数据(例如,从互联网加载 csv 文件)
- 浏览数据(例如,汇总统计、数据可视化等。)
- 清理数据(例如,处理丢失的数据)
- 转换数据(例如,特征工程、缩放、重新格式化为 Numpy 数组或 Spark RDD(弹性分布式数据集))
为方便起见,假设以下 Python 库已安装在 Mac 等本地机器上:
- Anaconda (conda 4.7.10)带有 Numpy、Pandas、Matplotlib 和 Scikit-Learn
- 火花 2.4.4
- 考拉
1.加载数据
在开始任何数据预处理之前,需要将数据集(例如,公共的 sample_stocks.csv 文件)加载到内存中。为此,让我们导入相关的 Python 库:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inlinefrom pyspark import SparkContexttry:
sc = SparkContext('local', 'Pyspark demo')
except ValueError:
print('SparkContext already exists!')from pyspark.sql import SparkSession
try:
spark = SparkSession.builder.appName('Recommendation_system').getOrCreate()
except ValueError:
print('SparkSession already exists!')
1.1 在 Pandas 中加载 csv 文件
Pandas 提供了一个 read_csv ()函数,既可以读取本地 csv 文件,也可以从互联网上读取 csv 文件作为 Pandas 数据帧:
pd_df = pd.read_csv("[https://raw.githubusercontent.com/databricks/koalas/master/data/sample_stocks.csv](https://raw.githubusercontent.com/databricks/koalas/master/data/sample_stocks.csv)")
pd_df.head(1)
1.2 在 Spark 中加载 csv 文件
在 Spark 中, SparkSession 只提供了一种从本地 csv 文件或内存中的 RDD 读取 Spark 数据帧的方法。Spark 需要与其他 Python 库结合使用,才能从互联网上远程读取 csv 文件。
一种方法是首先使用 URL 请求和响应包从互联网读取 csv 文件的内容,然后将内容转换为 SparkSession 的 Spark RDD,以作为 Spark 数据帧加载。
import urllib.requesturl = "[https://raw.githubusercontent.com/databricks/koalas/master/data/sample_stocks.csv](https://raw.githubusercontent.com/databricks/koalas/master/data/sample_stocks.csv)"
response = urllib.request.urlopen(url)
data = response.read()
text = data.decode('utf-8')
spark_df1 = spark.read.csv(sc.parallelize(text.splitlines()), header=True)
print(spark_df1.show(1))
另一种方法是首先使用 Pandas 读取 csv 文件作为 Pandas 数据帧,然后使用 SparkSession 从 Pandas 数据帧创建 Spark 数据帧。
spark_df2 = spark.createDataFrame(pd.read_csv(url))
1.3 在考拉中加载 csv 文件
像 Spark 一样,考拉只提供了从本地 csv 文件读取的方法。它需要与其他 Python 库结合才能从互联网上读取 csv 文件。一个简单的方法是首先使用 Pandas 读取 csv 文件作为 Pandas 数据帧,然后将其转换为 Koalas 数据帧。
import databricks.koalas as ks
ks_df = ks.from_pandas(pd.read_csv(url))
ks_df.head(1)
2.探索数据
一旦数据集作为数据帧加载到内存中,我们就可以使用数据帧的各种函数从不同的方面研究它。
2.1 了解数据框架模式
通常,探索数据帧的第一步是理解它的模式:列名和相应的数据类型。
对于 Pandas、Spark 和 Koalas 数据帧,获取数据帧列名和数据类型的方法是相似的。所有这些数据帧都为列名提供了属性 columns ,为列数据类型提供了属性 dtypes 。
需要注意的一点是,Spark DataFrame 的数据类型取决于示例公共 csv 文件的加载方式。如果通过 Spark 使用 URL 请求和响应包加载 csv 文件,则列数据类型默认为 string 类型,而如果通过 Pandas with Spark 加载 csv 文件,则列数据类型为 double 类型。
# DataFrame column names
pandas_column_names = pd_df.columns
spark_column_names = spark_df1.columns
ks_column_names = ks_df.columns# DataFrame column data type
pandas_column_data_types = pd_df.dtypes
spark_column_data_types = spark_df1.dtypes
ks_column_data_types = ks_df.dtypes
2.2 获取汇总统计数据
一旦我们理解了数据帧的模式,探索数据的下一步是查看汇总统计,例如五个数字汇总。所有的熊猫、Spark 和考拉数据帧都提供了相同的函数 describe ()来获得这些基本的汇总统计数据,包括数据帧中每一列的总行数、最小值、平均值、最大值和百分位数。
pd_df.describe()
spark_df1.describe()
ks_df.describe()
除了基本的汇总统计信息之外,汇总统计信息的另一个要素是数据帧中不同列之间的相关性。所有的熊猫、星火、考拉数据框架都提供了一个函数 corr ()来计算相关系数。熊猫和考拉 DataFrame 的 corr ()函数可以处理任意数量的列,但是 Spark DataFrame 的 corr ()函数只允许两列。
pd_df[['Open','Close', 'Volume']].corr()
ks_df[['Open','Close', 'Volume']].corr()
from pyspark.sql.functions import corr
spark_df2.select(corr("Open","Close")).show()
2.3 分组依据和聚合
分组依据和聚合(例如,最小值、最大值、平均值等。)是汇总统计的另一个要素。熊猫和考拉数据框架为分组依据和聚合提供了相同的功能:
pd_df.groupby('Symbol').max()['Open']
ks_df.groupby('Symbol').max()['Open']
但是,用于 group by 和 aggregation 的 Spark DataFrame 函数具有不同的格式:
from pyspark.sql.functions import max
spark_df2.groupBy("Symbol").agg(max("Open")).show()
2.4 可视化数据
数据可视化是理解数据的一种重要而有效的方法。熊猫和考拉数据框为数据可视化提供了类似的绘图功能,但绘图质量可能会有很大差异。例如,与熊猫数据框架散点图相比,下面的考拉数据框架散点图遗漏了许多数据点。
但是,Spark DataFrame 不直接提供任何数据可视化功能。一种简单的解决方法是将 Spark 数据帧转换为熊猫或考拉数据帧,以实现数据可视化。
pd_df_sub = pd_df[['Open', 'Close']]
pd_df_sub.plot.scatter(x='Open', y='Close')
ks_df_sub = ks_df[['Open', 'Close']]
ks_df_sub.plot.scatter(x='Open', y='Close')
熊猫和考拉 DataFrame 中的散点图函数只能处理两列。Pandas 绘图模块提供了一个 scatter_matrix ()函数,该函数可以为任意数量的列绘制散点图。
from pandas.plotting import scatter_matrix
pd_df_sub = pd_df[['Open', 'Close', 'Volume']]
scatter_matrix(pd_df_sub, alpha=0.2)
3.清理数据
数据清理的两个主要目标是处理丢失的数据和过滤掉异常值。
3.1 处理缺失数据
为了演示如何处理丢失的数据,首先让我们将一个丢失的数据项(例如,np.nan)分配到 Pandas 数据帧中:
pd_df_missing = pd_df.copy()
pd_df_missing.loc[0, 'Open'] = np.nan
pd_df_missing[pd_df_missing['Open'].isnull()]
Pandas DataFrame 提供了一个 fillna ()函数,可以用任意字符串或数字填充缺失的数据项。Spark 和 Koalas 数据帧提供了类似的功能,但是它们只允许与相应列的数据类型相匹配的值。
pd_df_missing.fillna('N/A', inplace = True)
pd_df_missing.fillna(0, inplace = True)# Spark and Koalas allow only a number
ks_df_missing.fillna(0, inplace = True)
spark_df_missing = spark_df_missing.na.fill(0)
3.2 过滤数据
数据过滤可用于去除异常值和许多其他目的。
如下面的示例代码所示,熊猫和考拉数据帧具有相同的 API,用于有条件地选择数据行和列。然而,Spark 数据帧有一个不同的 API。
pd_df.loc[pd_df['Open'] >= 168, ['Open','Close']].head()
ks_df.loc[ks_df['Open'] >= 168, ['Open','Close']].head()
spark_df.filter("Open > 168").select("Open","Close").show(5)
4.为特征工程转换数据
特征工程可以是机器学习应用的基础,并且可以通过各种类型的数据转换来实现。特征是数据帧中的数据列。功能工程的范围各不相同,但通常包括以下内容:
- 选择与机器学习中的预测目标相关的现有数据列的子集(即,受监督的机器学习中的标签)
- 用更有意义的名称重命名现有列
- 基于现有列创建新列(即创建衍生特征)
- 将列值缩放到特定范围内(即,在深度学习中将列值缩放到[0,1]或[-1,1]的范围内)
4.1 选择列
如前所述,Pandas 和 Koalas DataFrames 提供了相同的选择列的方法,但是 Spark DataFrame 提供了不同的 API。
pd_df[['Open', 'Close']]
ks_df[['Open', 'Close']]
spark_df.select('Open', 'Close')
4.2 重命名列
Pandas 和 Spark DataFrames 使用不同的函数名,但重命名列的功能相似。
pd_df.rename(columns = {"Symbol": "SYMBOL"}, inplace = True)
spark_df = spark_df.withColumnRenamed("Symbol", "SYMBOL")
但是,目前的考拉数据框架不支持重命名列的功能。
4.3 创建新列
机器学习通常需要从现有特征中派生新特征,即从现有列创建新数据列:
from pyspark.sql.functions import colpd_df['Sum'] = pd_df['Open'] + pd_df['Close']
ks_df['Sum'] = ks_df['Open'] + ks_df['Close']
spark_df1 = spark_df1.withColumn("Sum", col("Open") + col("Close"))
4.4 删除列
不必要的列(如 AdjOpen 和 AdjHigh )可以删除如下:
pd_df = pd_df.drop(['AdjOpen', 'AdjHigh'], axis=1)
ks_df = ks_df.drop(['AdjOpen', 'AdjHigh'], axis=1)
spark_df = spark_df.drop('AdjOpen', 'AdjHigh')
4.5 缩放列
如前所述,如果不同列的值在非常不同的范围内,则在机器学习中有必要将列的值缩放到某个范围内(例如,[0,1 或[-1,1])。对于 Pandas DataFrame,scikit-learn 库为此提供了两个常用函数 MinMaxScaler ()和 StandardScaler ()。
但是,这些函数不能直接应用于考拉数据帧。树袋熊数据帧需要转换成熊猫数据帧才能利用这些功能。
可以为 Spark 数据帧缩放列,但是与为 Pandas 数据帧使用 scikit-learn 函数相比,实现可能要复杂得多。例如,类似于 Spark 数据缩放示例,以下代码使用 Spark MinMaxScaler 、 VectorAssembler 和 Pipeline 对象来缩放 Spark 数据帧列:
from pyspark.ml.feature import MinMaxScaler
from pyspark.ml import Pipeline
from pyspark.ml.feature import VectorAssembler# VectorAssembler Transformation - Converting column to vector type
assembler = VectorAssembler(inputCols=['Open'], outputCol="Open_Vect")
scaler = MinMaxScaler(inputCol="Open_Vect", outputCol="Open_Scaled")# Pipeline of VectorAssembler and MinMaxScaler
pipeline = Pipeline(stages=[assembler, scaler])# Fitting pipeline on dataframe
spark_df3 = pipeline.fit(spark_df2).transform(spark_df2).drop("Open_Vect")
spark_df3.show(1)
4.6 一键编码
需要使用一键编码将分类数据类型列的值转换为数字数据类型的新列:
pd_df_dummies = pd.get_dummies(pd_df)
ks_df_dummies = ks.get_dummies(ks_df)
但是,Spark DataFrame 不提供这样的功能。一种解决方法是将数据帧转换为熊猫或考拉数据帧。
4.7 为机器学习重新格式化数据帧
数据预处理的最后一步是根据使用的机器学习库,将数据帧转换为机器学习建模使用的适当格式。
如果基于 Numpy 的机器学习或深度学习库(即 scikit-learn、Keras 等。)时,需要将 DataFrame 转换为 Numpy 数组进行建模。Pandas DataFrame 提供了一个 values 属性来从 Pandas DataFrame 中获取一个 NumPy 数组。但是现在的考拉数据框架不支持这样的方法。如果数据集可以在单台机器上处理,Spark 或 Koalas 数据帧可以转换为 Pandas 数据帧,如下所示,以便轻松获得相应的 Numpy 数组。
pd_df_from_koalas = ks_df.to_pandas()
pd_df_from_spark = spark_df.toPandas()
如果使用像 MLlib 这样的基于 Spark 的机器学习库,那么需要将数据帧转换成 RDD 或 Spark 数据帧。一个 Spark 数据帧可以直接馈入一个适当设计的 MLlib 流水线(例如参见 MLlib )或者转换成 RDD,如果基于 RDD 的 MLlib API 用于建模的话。Spark 数据帧提供了一个 rdd 属性来返回一个 rdd。在这种情况下,熊猫或考拉数据帧需要首先转换为 Spark 数据帧,以便进行建模。这可以通过以下方式实现:
spark_df_from_pandas = spark.createDataFrame(pd_df)
spark_df_from_koalas = ks_df.to_spark()
摘要
正如在考拉公告中所描述的,数据科学家倾向于使用熊猫数据框架来探索数据。由于陡峭的学习曲线,他们不愿意使用 Spark DataFrame。考拉似乎通过提供一个易于使用的 API 来填补它们之间的空白,该 API 类似于可以在 Spark 上运行的熊猫 DataFrame。
在这篇文章中,正如下面的汇总表所示,我使用了一个公共数据集sample _ stocks . CSV来评估和比较机器学习的典型数据预处理任务中熊猫、Spark 和考拉数据帧的基本功能。
考拉还处于发育初期。如上表所示,它不支持数据预处理的一些基本功能。某些支持的功能尚未成熟。随着开发的推进,考拉在 Spark 上易于使用的数据转换和可视化 API 的许多潜在优势将在大规模数据集(例如,数亿条数据记录)的情况下开始闪耀。
披露声明:2019 首创一。观点是作者个人的观点。除非本帖中另有说明,否则 Capital One 不隶属于所提及的任何公司,也不被这些公司认可。使用或展示的所有商标和其他知识产权是其各自所有者的财产。
Python 数据科学和分析/咨询项目概述
从科技公司的角度比较国家候选资格/市场性;分析时间状态、物流、本地资源等…
所以为了支持我进入咨询行业的目标,我决定提高我的分析组合的有形性至关重要。这是通过考虑我对大数据/分析的真正兴趣和其中的决策权,以及对大多数咨询公司普遍存在的入门级“分析师”角色的检查而决定的。
你有大量的数据分析专业知识,但是你如何展示这些知识呢?
因此,扩大我的投资组合将在多个方面让我受益。这将进一步培养我真正着迷的技能,一种我真正投入成长的技能。这将有利于以后的职业发展,并加快可扩展的决策。最后,通过使我的技能组合更加有形,这将增加我的咨询职位的候选人资格。
对于后一点,让我的项目和投资组合面向咨询是最有意义的。
选择特定的行业/客户仅仅是基于我自己的兴趣,以及一个非常标准的行业分析。我一直对技术感兴趣。如今,几乎所有发展最快的行业都在“科技”的保护伞下。技术是我们过去几十年的决定性特征,并且毫无疑问将在未来继续如此。因此,技术行业将是我项目的背景焦点——但我会努力同时保持它足够广泛,以展示其他行业的应用。
因此,我的项目基于以下关键问题:
- 当今最强大、发展最快、用途最广泛的数据科学语言是什么?
- 顾问满足的最常见的客户需求是什么?/客户最常要求咨询公司提供什么服务?
- 今天大多数企业在哪里面临困难?
这些问题的答案是我这个项目的根源:
- 计算机编程语言
- 市场分析/市场进入和扩张
- 有效利用技术和数据;全局可扩展性
ython 是当今数据科学领域最具活力的语言。从后端开发,到深入的 ML 学习和统计分析。它直观、灵活,也许最重要的是,从开源的角度来看,它得到了广泛的支持。它相当容易学习,而且非常强大。在分析和统计方面,可能只有 R 能与之匹敌。
值得庆幸的是,我在学术界的分析经验的核心,主要是建立在 R 之上的。因此,我已经对 R 有了足够的认识和理解。通过展示我能够迅速适应和运用一种完全不同的语言,我将进一步提高我的候选资格。此外,Python 的后台逻辑/框架对于那些对数据科学了解不多的人来说更优雅,更容易理解。
Python 将是我在这个项目中使用的工具。
市场分析在咨询界非常流行。以至于大多数咨询面试几乎肯定会在某种程度上包含这一点。这是有道理的,因为公司在考虑候选人时考察的一般“适合度”是以思维为中心的。候选人能使用一个可解释的框架来组织他们的思想吗?他们看问题的逻辑直观务实吗?
这些特质通常会在回答有点模糊的问题时表现出来。从商业的角度来看,市场分析也足够广泛,它显示了一个人看到全局的能力,从而允许他们更有效地创新他们的问题解决方法。
当把商业环境作为一个整体来考察时,市场分析作为我项目的中心在逻辑上得到了支持。随着云、数字营销和一般物联网的发展,所有公司现在都希望拥有全球影响力,而这在过去只是行业领导者的专利。但是假设你有能力跨越世界;你把注意力放在哪里?你怎么知道的?数据科学支持的市场分析回答了这两个问题。
假设公司能够有效地使用数据并从中获得洞察力。从战略角度来看,他们具体想要实现什么?成长。很像普通的金鱼,在这种生长中最有影响力的成分是什么?环境。
金鱼会根据它的碗的大小而生长
企业想要也需要一个更大的“碗”
有了云,他们现在有了海洋。
G 全球可扩展性不仅仅是触及过去无法触及的客户。虽然市场分析可以告诉客户将他们的资源集中在哪里,并以经验数据支持这一决定,但另一个更深层次的问题是更加务实的“如何做?”
使我对这种全球扩展的理解更加具体,是我获得 AWS 云认证的原因之一。
顾问需要检查客户的能力。也许全球都有市场机会,可以通过数字方式联系到客户。但是体能和限制仍然存在。在这个过程中,需要考虑供应链、采购和物流。因此,分析合规性、关税、边界、材料/资源可用性等是这个项目的主要组成部分之一。
将这三个主要因素结合起来,就产生了最佳的项目。
使用 Python 的强大功能和多功能性,在全球范围内,针对通用技术行业内不同容量的假设客户,对非结构化大数据进行广泛的市场分析。
用于 ETL 的 Python 数据转换工具
**免责声明:**我不是 ETL 专家,我欢迎在这个领域更有经验的人的任何评论、建议或批评。
前几天,我在 Reddit 上询问我是否应该使用 Python 进行 ETL 相关的转换,压倒性的回应是是的。
source: Pinclipart
然而,虽然我的 Redditors 同事热情地支持使用 Python,但他们建议看看 Pandas 以外的库——引用了对 Pandas 处理大型数据集的性能的担忧。
在做了一些研究之后,我发现了大量为数据转换而构建的 Python 库:一些提高了 Pandas 的性能,而另一些提供了自己的解决方案。
我找不到这些工具的完整列表,所以我想我应该利用我所做的研究来编译一个——如果我遗漏了什么或弄错了什么,请让我知道!
熊猫
概述
熊猫当然不需要介绍,但我还是要给它介绍一下。
Pandas 将数据帧的概念添加到 Python 中,并在数据科学社区中广泛用于分析和清理数据集。作为 ETL 转换工具,它非常有用,因为它使得操作数据变得非常容易和直观。
优点
- 广泛用于数据操作
- 简单、直观的语法
- 与包括可视化库在内的其他 Python 工具集成良好
- 支持通用数据格式(从 SQL 数据库、CSV 文件等读取。)
弊端
- 因为它将所有数据加载到内存中,所以它是不可伸缩的,并且对于非常大(大于内存)的数据集来说可能是一个糟糕的选择
延伸阅读
达斯克
概述
根据他们的网站,“Dask 是一个灵活的 Python 并行计算库。”
本质上,Dask 扩展了公共接口,如 panda,用于分布式环境中——例如,Dask DataFrame 模仿 panda。
优点
- 可扩展性— Dask 可以在您的本地机器上运行和扩展到一个集群
- 能够处理不适合内存的数据集
- 即使在相同的硬件上,也能以相同的功能提高性能(得益于并行计算)
- 从熊猫切换的最小代码更改
- 旨在与其他 Python 库集成
弊端
- 除了并行性,还有其他方法可以提高 Pandas 的性能(通常更显著)
- 如果你正在做的计算量很小,那就没什么好处
- 有些功能没有在 Dask 数据帧中实现
延伸阅读
摩丁
网址:https://github.com/modin-project/modin
概述
Modin 与 Dask 相似,它试图通过使用并行性和启用分布式数据帧来提高 Pandas 的效率。与 Dask 不同,Modin 基于任务并行执行框架 Ray 。
与 Dask 相比,Modin 的主要优势在于,Modin 自动处理跨机器内核的数据分发(无需配置)。
优点
- 可伸缩性 Ray 比 Modin 提供的更多
- 即使在相同的硬件上,也能以完全相同的功能提高性能
- 从 Pandas 切换的最小代码更改(更改导入语句)
- 提供 Pandas 的所有功能——比 Dask 更像是一个“嵌入式”解决方案
弊端
- 除了并行性,还有其他方法可以提高 Pandas 的性能(通常更显著)
- 如果你正在做的计算量很小,那就没什么好处
延伸阅读
petl
网址:https://petl.readthedocs.io/en/stable/
概述
petl 包含了 pandas 拥有的许多特性,但是它是专门为 etl 设计的,因此缺少额外的特性,比如那些用于分析的特性。petl 拥有 etl 所有三个部分的工具,但是这篇文章只关注数据转换。
虽然 petl 提供了转换表的能力,但是其他工具(比如 pandas)似乎更广泛地用于转换,并且有很好的文档记录,这使得 petl 在这方面不太受欢迎。
优点
- 最大限度地减少系统内存的使用,使其能够扩展到数百万行
- 对于 SQL 数据库之间的迁移非常有用
- 轻巧高效
弊端
- 通过最大限度地减少系统内存的使用,petl 的执行速度较慢——对于性能非常重要的应用程序,不推荐使用它
- 与列表中的其他数据操作解决方案相比,较少使用
延伸阅读
PySpark
概述
Spark 旨在处理和分析大数据,并提供多种语言的 API。使用 Spark 的主要优势是 Spark 数据帧使用分布式内存并利用延迟执行,因此它们可以使用集群处理更大的数据集——这是 Pandas 等工具所无法实现的。
如果您正在处理的数据非常大,并且数据操作的速度和大小非常大,那么 Spark 是 ETL 的一个好选择。
优点
- 更大数据集的可扩展性和支持
- Spark 数据帧在语法方面与 Pandas 非常相似
- 通过 Spark SQL 使用 SQL 语法进行查询
- 与其他流行的 ETL 工具兼容,包括 Pandas(您实际上可以将 Spark 数据帧转换成 Pandas 数据帧,使您能够使用所有其他类型的库)
- 兼容 Jupyter 笔记本电脑
- 对 SQL、流和图形处理的内置支持
弊端
- 需要分布式文件系统,如 S3
- 使用像 CSV 这样的数据格式限制了延迟执行,需要将数据转换成其他格式,比如 T21 的拼花地板
- 缺乏对 Matplotlib 和 Seaborn 等数据可视化工具的直接支持,这两个工具都得到 Pandas 的良好支持
延伸阅读
值得注意的提及
虽然我想这是一个全面的列表,但我不想这篇文章变得太长!
确实有很多很多用于数据转换的 Python 工具,所以我在这一部分至少提到了我错过的其他项目(我可能会在本文的第二部分进一步探讨这些项目)。
- 倭 https://www.bonobo-project.org/
- 气泡 http://bubbles.databrewery.org/
- pygrametl http://chrthomsen.github.io/pygrametl/
- 阿帕奇光束
https://beam.apache.org/
结论
我希望这个列表至少能帮助您了解 Python 为数据转换提供了哪些工具。在做了这项研究之后,我确信 Python 是 ETL 的一个很好的选择——这些工具和它们的开发者已经使它成为一个令人惊奇的使用平台。
正如我在这篇文章的开头所说,我不是这方面的专家——如果你有什么要补充的,请随时评论!
感谢阅读!
Python 字典从零开始!!!
让我们了解一下 python 中字典的基础知识。
Credits: Learntek
python 中的 Dictionary 包含一个以 key: value 格式存储的无序数据集合。字典也被称为“联想记忆”或“联想数组”。在字典中,键必须总是唯一的。而这些值可以重复,并且可以是任何数据类型。键值对应该表示为“key: value”(:冒号是必须的)。下面是一些最常用的字典方法,也是最常见的面试问题之一。此外,代码可以在我的 GitHub 页面上找到。
比如用 python 声明一个字典:
**# Declaring a dictionary**dictionary = {}dictionary = {'Name': 'Tanu', 'Sex': 'Male', 'Age': 23}
print(dictionary)**{'Name': 'Tanu', 'Sex': 'Male', 'Age': 23}**print(type(dictionary))**dict**
1)访问字典中的元素
字典可以通过它们的索引来获取值。要做到这一点,您所要做的就是将数字或键的名称与字典的名称一起放在一对方括号内。
**# Accessing the elements in a dictionary**dictionary = {‘Name’: ‘Tanu’, ‘Sex’: ‘Male’, ‘Age’: 23}
print(dictionary)**{'Name': 'Tanu', 'Sex': 'Male', 'Age': 23}**print(dictionary['Name'])**'Tanu'**print(dictionary['Sex'])**'Male'**
如果您尝试访问字典中未声明的键,则会引发异常,指示未找到任何结果:
print(dictionary[‘Height’])**--------------------------------------------------------------------****KeyError Traceback (most recent call last)**[**<ipython-input-9-038ad6c9b2d4>**](/<ipython-input-9-038ad6c9b2d4>) **in <module>()
----> 1 dictionary['Height']****KeyError: 'Height'**
同样,我们可以使用字典的 get()来获取或访问字典的值,如下所示:
print(dictionary.get(‘Age’))**23**
2)从字典中删除元素。
在 python 中,有四种不同的方式或方法可用于从字典中移除元素。它们是 pop、del、popitem 和 clear。del 用于从字典中删除一个键,pop 用于从字典中删除特定的键,popitem 用于从字典中任意删除该键,clear 用于清除或删除字典中的所有元素(顾名思义)。
**# Removing the elements from a dictionary**dictionary = {'Name': 'Tanu', 'Sex': 'Male', 'Age': 23, 'Height': 5.8, 'Occupation': 'Student'}
print(dictionary)**{'Name': 'Tanu', 'Sex': 'Male', 'Age': 23, 'Height': 5.8, 'Occupation': 'Student'}****--------------------------------------------------------------------****# Deleting an element**del dictionary['Name']
print(dictionary)**{'Sex': 'Male', 'Age': 23, 'Height': 5.8, 'Occupation': 'Student'}****--------------------------------------------------------------------****# Popping an item**print(dictionary.popitem())**('Occupation', 'Student')****--------------------------------------------------------------------****# Popping the value**dictionary.pop('Sex')**'Male'****--------------------------------------------------------------------**print(dictionary)**{'Age': 23, 'Height': 5.8}****--------------------------------------------------------------------****# Clearing the entire dictionary**dictionary.clear()
print(dictionary)**{}**
3)遍历字典
使用 for 循环,我们可以遍历字典中的每个键,如下所示:
dictionary = {‘Name’: ‘Tanu’, ‘Sex’: ‘Male’, ‘Age’: 23, ‘Height’: 5.8, ‘Occupation’: ‘Student’}
print(dictionary)**{'Name': 'Tanu', 'Sex': 'Male', 'Age': 23, 'Height': 5.8, 'Occupation': 'Student'}****# Iterating through the values**for i in dictionary:
print(dictionary[i])**Tanu
Male
23
5.8
Student****--------------------------------------------------------------------****# Iterating through the keys**for i in dictionary:
print(i)**Name
Sex
Age
Height
Occupation**
所有
如果字典的所有键都为真(或者如果字典为空),则字典中的 all()返回“真”。如果字典中的键为 true,或者如果 dictionary all 方法返回 true,否则将返回 false。
dictionary = {0: “Tanu”, 1: “Prabhu”}
print(dictionary)**{0: 'Tanu', 1: 'Prabhu'}**print(all(dictionary))**False**dictionary = {1: "Tanu", 1: "Prabhu"}
print(all(dictionary))**True**dictionary = {}
print(all(dictionary))**True**
5)任何
如果字典中的任意键为真,字典中的 any()返回“真”。如果字典为空,则返回“False”。
dictionary = {0: “Tanu”, 1: “Prabhu”}
print(dictionary)**{0: 'Tanu', 1: 'Prabhu'}**print(any(dictionary))**True**dictionary = {0: "Tanu", 0: "Prabhu"}
print(any(dictionary))**False****# 0 is False**dictionary = {0: "Tanu"}
print(any(dictionary))**False**
6)透镜
字典中的 length()方法返回字典的长度(很明显)。它返回字典的条目数。
dictionary = {‘Name’: ‘Tanu’, ‘Sex’: ‘Male’, ‘Age’: 23, ‘Height’: 5.8, ‘Occupation’: ‘Student’}
print(dictionary)**{'Name': 'Tanu', 'Sex': 'Male', 'Age': 23, 'Height': 5.8, 'Occupation': 'Student'}**print(len(dictionary))**5**
7)排序
dictionary 中的 Sorted()方法返回字典中新排序的键列表。
dictionary = {‘Name’: ‘Tanu’, ‘Sex’: ‘Male’, ‘Age’: 23, ‘Height’: 5.8, ‘Occupation’: ‘Student’}
print(dictionary)**{'Name': 'Tanu', 'Sex': 'Male', 'Age': 23, 'Height': 5.8, 'Occupation': 'Student'}****# Sorting in a ascending order**print(sorted(dictionary))**['Age', 'Height', 'Name', 'Occupation', 'Sex']****# Sorting in a descending order**print(sorted(dictionary, reverse = True))**['Sex', 'Occupation', 'Name', 'Height', 'Age']**
sorted()方法接受一个反向参数作为可选参数。
8)复制
顾名思义,dictionary 中的 copy 方法返回字典的副本。
dictionary = {‘Name’: ‘Tanu’, ‘Sex’: ‘Male’, ‘Age’: 23, ‘Height’: 5.8, ‘Occupation’: ‘Student’}
print(dictionary)**{'Name': 'Tanu', 'Sex': 'Male', 'Age': 23, 'Height': 5.8, 'Occupation': 'Student'}**dictionary1 = {}
print(dictionary1)**{}**dictionary1 = dictionary.copy()
dictionary1**{'Name': 'Tanu', 'Sex': 'Male', 'Age': 23, 'Height': 5.8, 'Occupation': 'Student'}**
9)钥匙
Python 字典方法 key()返回字典中所有可用键的列表。
dictionary = {‘Name’: ‘Tanu’, ‘Sex’: ‘Male’, ‘Age’: 23, ‘Height’: 5.8, ‘Occupation’: ‘Student’}
print(dictionary)**{'Name': 'Tanu', 'Sex': 'Male', 'Age': 23, 'Height': 5.8, 'Occupation': 'Student'}**print(dictionary.keys())**dict_keys(['Name', 'Sex', 'Age', 'Height', 'Occupation'])**
十)价值观
Python 字典方法 values()返回给定字典中所有可用值的列表。
dictionary = {‘Name’: ‘Tanu’, ‘Sex’: ‘Male’, ‘Age’: 23, ‘Height’: 5.8, ‘Occupation’: ‘Student’}
print(dictionary)**{'Name': 'Tanu', 'Sex': 'Male', 'Age': 23, 'Height': 5.8, 'Occupation': 'Student'}**print(dictionary.values())**dict_values(['Tanu', 'Male', 23, 5.8, 'Student'])**
因此,以上是 Python 中非常重要的字典技术或函数。一些例子是从 Python 字典中引用的。我用一种简单的方式写了这篇教程,这样每个人都可以理解和掌握 Python 中字典的概念,而不需要以前的编程知识或经验。如果你们对代码有什么疑问,评论区就是你们的了。谢谢,祝你愉快。
Python 效率技巧:有抱负的 python 爱好者的新旧技巧
这是给予的季节。本着节日的精神,我在 Googleverse 上搜索了一些有趣的、或许不为人知的(直到现在)提高完美主义者 Pythonista 效率的技巧。
- tqdm()
tqdm()是一个包装器,用于即时显示“for”循环的智能进度表。它需要一个安装和一个导入,但是如果您曾经有过一个循环,看起来花费的时间比它应该花费的时间长,这可以提供一些需要的洞察力。
tqdm() and trange() in action — trange is just a bit faster than using range() within tqdm()
2。Shift 和 Tab 键(Windows 操作系统)
这个技巧实际上为我节省了很多去 Stackoverflow 的时间,但我有时还是会忘记使用它。这里有几个用途:
- 结束你的思考。在使用了一段时间后,记住正确的库或变量有时会很困难。只需在一个字母后使用选项卡按钮,就会弹出一个以该字母开头的术语或实例化变量的下拉列表。
Just type in a letter and use Tab to see a list of options
- 包/特性/方法文档。通过组合 Shift + Tab,将为该项弹出一个 docstring 和说明。在 Jupyter 笔记本中有三种查看方式:
Standard window with argument(s) and brief docstring
Using the + button will reveal full documentation, including parameters, examples and website
Using the ^ button will embed a bottom pane with the full documentation.
- f 弦
对于那些仍然使用 str.format()或%d(替换为数字),%s(替换为字符串)的人来说,f 字符串更有效。f 字符串可以在代码中的任何地方被调用,并且可以引用任何以前实例化的变量。下面是一些如何使用它们的例子:
Using ‘ ‘ , “ “ and ‘’’ ‘’’ are all valid methods, and most datatypes can be utilized
Math operations, string concatenation and methods can be performed within f-strings
Dictionary values can also be called out in f-strings
However, some symbols cannot be used within an f-string. Most operator keys like @,&,!,= can.
- IPython Magic
IPython 有一个名为 magic 的内置库,允许用户只需以%符号开头就可以运行特定的命令。魔法有两种形式:
- 行魔法:它们类似于命令行调用。它们以%字符开始。该行的其余部分是传递的参数,没有括号或引号。线条魔术可以用作表达式,它们的返回值可以赋给变量。
- 细胞魔术:他们有%%字符前缀。与线路魔术功能不同,它们可以在呼叫下方的多条线路上操作。事实上,他们可以对接收到的输入进行任意修改,甚至根本不需要是有效的 Python 代码。它们将整个块作为单个字符串接收。
有许多神奇的命令,最著名的是%timeit(乘以你的代码)和%matplotlib inline。要获得可以调用的命令的完整列表,只需运行以下单元格:
Just type %magic into your notebook for a complete doc on available commands
- Walrus 操作符(python 3.8 的新功能)
对于那些运行 3.8 的人来说(注意:在这篇文章发表时,并不是所有的包都准备好了 3.8),这里有一个新的操作符,它使得执行操作更有效率。=运算符、赋值运算符或 walrus 运算符(因为它看起来像长着獠牙的眼睛)允许用户在指定的函数或方法中为变量赋值。虽然在文档中可以举例说明几种用法,但这里只举例说明最简单的使用情况:
#old way
answer = False
print(answer)#new way
print(answer := False)
这里的希望是,也许您发现了一些有助于提高 Python 效率的东西,或者激发您的兴趣去探索一些更高效的方法。请随意回复任何其他效率提示。节日快乐!
Python enumerate()内置函数
在本教程中,让我们了解 python 中的枚举内置函数。
定义
枚举器内置函数 将可迭代数 的计数器添加到所提供的整数、字符或字符串等数据结构中。现在,数据结构可能是任何列表、元组、字典或集合。如果计数器不是由用户提供的,那么默认情况下它从 0 开始。基于所提供的数字,枚举器函数进行迭代。
句法
枚举器内置函数的语法如下:
**enumerate(iterable, start)**
因素
枚举器函数的参数是 iterable 和 start。
- iterable: 这是希望迭代的数据结构的名称。
- start: 这是您想要开始迭代计数器的数字。
注意:iterable 必须是支持迭代的对象。
如果您想知道枚举函数的实际语法,只需在您的 IDE 上键入 help(enumerate ),然后您将获得以下结果。因为你需要了解这些东西。
**Help on class enumerate in module builtins:** **class enumerate(object)
| enumerate(iterable[, start]) -> iterator for index, value of | iterable
|
| Return an enumerate object. iterable must be another object that | supports iteration. The enumerate object yields pairs containing | a count (from start, which defaults to zero) and a value yielded | by the iterable argument. enumerate is useful for obtaining an | indexed list:(0, seq[0]), (1, seq[1]), (2, seq[2]), ...
|
| Methods defined here:
|
| __getattribute__(self, name, /)
| Return getattr(self, name).
|
| __iter__(self, /)
| Implement iter(self).
|
| __new__(*args, **kwargs) from builtins.type
| Create and return a new object. See help(type) for accurate | signature.
|
| __next__(self, /)
| Implement next(self).
|
| __reduce__(...)
| Return state information for pickling.**
返回类型
枚举函数的返回类型是 对象 类型。因此 enumerate 函数通过向对象添加迭代计数器值来返回该对象。还可以将枚举器对象转换成 list()、tuple()、set()等等。
让我们看一个例子,了解一下枚举函数。
programmming = ["Python", "Programmming", "Is", "Fun"]
print(type(programmming))enum = enumerate(programmming)print(type(enum))*#Converting to a list* print(list(enum))*#Converting to a tuple* print(tuple(enum))*#Converting to a set* print(set(enum))
当您运行该程序时,您将获得以下输出:
**<class 'list'>
<class 'enumerate'>
[(0, 'Python'), (1, 'Programmming'), (2, 'Is'), (3, 'Fun')]
((0, 'Python'), (1, 'Programmming'), (2, 'Is'), (3, 'Fun'))
{(3, 'Fun'), (2, 'Is'), (0, 'Python'), (1, 'Programmming')}**
可选参数
枚举函数也接受可选参数,您也可以传递数据结构的名称以及您想要启动计数器的特定索引。例如,认为列表的默认值从 0 开始,然后计数器继续迭代。现在你想从 5 开始计数,然后递增计数。这可以按如下所示完成:
programmming = ["Python", "Programmming", "Is", "Fun"]# Counter value starts from 0
enum = enumerate(programmming)
print(list(enum))# Counter value starts from 5
enum = enumerate(programmming, 5)
print(list(enum))
当您运行该程序时,您将获得以下输出:
**[(0, 'Python'), (1, 'Programmming'), (2, 'Is'), (3, 'Fun')]****[(5, 'Python'), (6, 'Programmming'), (7, 'Is'), (8, 'Fun')]**
遍历枚举对象
让我们看看如何循环遍历枚举,如下所示:
programmming = ["Python", "Programmming", "Is", "Fun"]for i in enumerate(programmming):
print(i)for i in enumerate(programmming, 10):
print(i)
当您运行该程序时,输出将是:
**(0, 'Python')
(1, 'Programmming')
(2, 'Is')
(3, 'Fun')****(10, 'Python')
(11, 'Programmming')
(12, 'Is')
(13, 'Fun')**
关于“ Python enumerate()内置函数 ”的教程到此结束,这是一个很短的教程,因为这个概念很小,你用它能做的事情不多。了解枚举函数的概念真的很重要,这样你就可以在其他地方应用这个概念了。要阅读枚举函数的官方文档,请访问下面的链接:
[## 内置函数- Python 3.8.0 文档
Python 解释器内置了许多始终可用的函数和类型。它们被列出…
docs.python.org](https://docs.python.org/3/library/functions.html#enumerate)
此外,完整的代码可以在下面我的 GitHub 库中找到:
此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…
github.com](https://github.com/Tanu-N-Prabhu/Python/blob/master/Python_enumerate%28%29_built_in_function.ipynb)
好了,该说再见了,请继续关注阅读更多 python 教程。我希望你喜欢阅读本教程。祝你今天开心!玩的开心!
Python eval()内置函数
让我们了解一下 python 中的 eval()内置函数。
这将是一篇关于 python 中的 eval 函数的短文,其中我将向您解释 eval 函数、它的语法以及面试中经常被问到的几个问题,以便您清楚地理解它并轻松地回答这些问题。要获得完整代码,请点击下面的我的 GitHub 库:
此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…
github.com](https://github.com/Tanu-N-Prabhu/Python/blob/master/Eval_built_in_function.ipynb)
让我们开始吧:
1.python 中的 eval()是什么,语法是什么?
回答: eval 是 python 中使用的内置函数,eval 函数解析 expression 参数并将其作为 python 表达式求值。简单来说,eval 函数像 python 表达式一样对“字符串”求值,并将结果作为整数返回。
句法
eval 函数的语法如下所示:
**eval(expression, [globals[, locals]])**
自变量或参数
eval 函数的自变量或参数是字符串,也可以是全局的,局部变量可以用作 eval 函数内部的自变量,但是全局变量必须表示为字典,局部变量表示为映射对象。
返回值
返回值将是计算表达式的结果。返回类型通常是整数。
2.eval 函数在哪里最常用?
Eval 函数主要用于需要计算数学表达式的场合或应用。此外,如果用户希望将字符串转换为代码,那么可以使用 eval 函数,因为 eval 函数会计算字符串表达式并返回整数作为结果。
3.input()和 eval()有什么区别?
现在大家都知道 input()接受用户输入,但是当用户输入一个整数作为输入时,input 函数返回一个字符串,但是在 eval 的情况下,它会将返回值从字符串计算为整数。我知道你们大多数人都很困惑,让我举个例子来消除你们的困惑:
input = input("Enter any number of your choice:")
print(input)
print(type(input))
--------------------------------------------------------------------**Enter any number of your choice: 10 + 10
10 + 10
<class 'str'>**
看,就像我说的,我输入了一个整数 10+ 10 ,我期望的结果是 20 (10 + 10) ,但是输入方法返回了一个与输入相同的字符串。
eval = eval(input("Enter any number of your choice"))
print(eval)
print(type(eval))
--------------------------------------------------------------------**Enter any number of your choice: 10 + 10
20
<class 'int'>**
在 eval 的情况下,它以整数的形式返回计算后的表达式 20 ,给定字符串作为输入。 10 + 10 是一个结果为 20 的表达式。
4.能否用 eval 函数进行数学运算,举个例子?
是的,我们可以使用 eval 函数执行数学运算,如下所示:
evaluate = input(“Enter what operation x has to perform: “)
print(evaluate)
print(type(evaluate))
--------------------------------------------------------------------
**Enter what operation x has to perform: x + x + 100 - 35 + 5 * 80
x + x + 100 - 35 + 5 * 80
<class 'str'>**x = 10
print(type(x))
--------------------------------------------------------------------**<class 'int'>**expression = eval(evaluate)
print(expression)
print(type(expression))
--------------------------------------------------------------------
**485
<class 'int'>**
就像我说的,如果你以字符串的形式给出输入,eval 函数计算表达式,并以整数的形式返回结果。
这就是你开始使用 python 中的 eval 函数所需要知道的一切,现在你已经知道了上述问题的所有答案。同样的问题可能不会一直被问到,关键是要更好地了解概念,然后你才能回答任何问题。如果您想花些时间阅读一些关于 eval 函数的材料,我建议大家阅读下面所示的 eval 函数文档:
[## 内置函数- Python 3.8.0 文档
Python 解释器内置了许多始终可用的函数和类型。它们被列出…
docs.python.org](https://docs.python.org/3/library/functions.html#eval)
谢谢各位,这是文章的结尾就像我说的这是一篇小文章。如果你们有什么疑问或者遇到了什么困难,请在下面的评论区告诉我,我一定会回答你们所有的问题。好了,该说再见了,祝你有美好的一天。
Python 练习:计算一手 A 牌的所有可能值
这比我最初想的更有趣/复杂,因此写了这篇文章
我最近发表了一篇关于如何用 Python 模拟 21 点的博客。我仍然在做那个博客的后续工作,但是我想在那里得到这个免费的帖子。
在我发表了我最初的 21 点帖子后不久,Twitter 用户@DonBeham 友好地指出,在某些情况下(因为 ace),我的代码产生的手牌值将是错误的。
所以我去修复我的错误,并意识到计算 ace 值比我最初想象的要复杂得多。我们来探究一下原因。
你可以在我的 GitHub 上找到下面的代码以及我的 21 点代码。
挑战
写一个函数来计算一手牌的 21 点数值。
似乎很简单。
除了 a 可以值 1 分或 11 分,这取决于你手牌其余部分的价值。如果你的其他牌值 9 分,那么 a 值 11 分,这样你总共有 20 分。另一方面,如果你的其他牌值 19 分,a 现在值 1 分,这仍然给你 20 分。
听起来不算太糟,对吧。让我们看看复杂性是从哪里来的:
- 一手牌可以有任意数量的 a。鉴于赌场通常使用至少六副牌的牌叠,你最终可能拿到三张、四张甚至五张 a,这是非常不可能的,但肯定不是不可能的。所以我们需要逻辑来解释这些罕见的情况。
- 你手中 a 的价值不仅取决于你拿到 a 时已经有的牌,还取决于你将来会拿到的牌。例如,如果你的手牌是[a,7],那么它现在值 11+7=18 点。你得到一张王牌,这是一手更新的[王牌,7,王牌]——你的牌值增加到 11+7+1 = 19;不太复杂,因为我们知道,我们获得的每一个额外的 ace 都只值 1 分(因此我们不会超过 21 分)。现在,让我们把它变得更复杂一点——你拿到一张 5,给你[a,7,a,5]。保持之前的 ace 值 11 和 1,我们的手牌值为 11+7+1+5=24。这将超过 21,因此破产,所以现在我们拥有的每张 a 应该只值 1 分。
二十一点解决方案
针对 21 点的解决方案还不算太差。事情是这样的:
- 如果我们手中没有 a,那么 a 的值显然为零——首先我们需要检查这一点。
- 我们知道我们手里的 a 只有一张能值 11 分。否则我们会破产——例如,11+11=22。
- 因此,如果我们手里一张王牌值 11,其他值 1 的牌总数小于或等于 21,那么保留当前的王牌值(其中一张值 11,其余值 1)。
- 否则,如果一张 a 值 11,其他值 1 的手牌总数大于 21,则将所有 a 值设为 1。
#Check if the value of non-ace cards plus aces with one ace worth 11 #and the rest worth 1 is less than or equal to 21if num_aces > 0:
if non_ace_total + 11 + (num_aces - 1)*1 <= 21:
ace_value = 11 + (num_aces - 1)*1
else:
ace_value = num_aces*1
else:
ace_value = 0
hand_total = non_ace_total + ace_value
很简单。但是,除了 21 点以外,还有什么更通用的解决方案呢?现在,我们知道只有一张 a 值 11,这对我们很有帮助。但是如果破产的门槛本身就是一个可变的变量呢?你也许仍然可以用一堆“如果语句”来做这件事,但是会很麻烦。相反,让我们写一个更一般的解决方案。
广义解
让我们试着想出一个更通用的解决方案。我想到的是用树。
- 我想找出 ace 值的所有排列。例如,对于两个 ace,它将是[1,1],[1,11],[11,1],[11,11]。我实际上想找到 ace 值的所有组合,但我发现先得到排列,然后过滤掉重复的更容易。
- 然后我把它们加起来——2,12,12,22。
- 最后,我想要唯一的值— 2,12,22。从这组值中,我可以选择最符合我的游戏规则的数字。
那么我们如何得到所有的排列呢?我首先想到的是嵌套的 for 循环。但这只有在你预先知道有多少个 ace 的情况下才有效,例如,如果你有 3 个 ace,那么你需要循环 A,B 和 C,其中 C 嵌套在 B 中,B 又嵌套在 A 中。
ace_values = []for A in [1,11]:
for B in [1,11]:
for C in [1,11]:
ace_values.append(A+B+C)unique_ace_values = set(ace_values)
但关键是我们不知道会有多少个 a——所以我们不知道我们需要多少个 for 循环。
我的回答是用一棵树。我们可以把每个 ace 看作两个分支(如果我的树术语不正确,我道歉),其中第一个分支对应于 1,第二个分支对应于 11。如果我们持有第二张 a,那么每个分支再次分裂,因此总共有 4 个叶节点,对应于手牌值 2、12、12 和 22。下图显示了我刚才描述的两个 ace 案例。
Using a tree to find all permutations for two aces
使用我们的树结构,我们可以通过遍历树直到到达每个叶节点来得到每个排列:
- 向上,向上—在第一次分割时获取 1,然后在叶节点再次获取 1。
- 向上,向下—得到 1,然后是 11。
- 向下,向上—得到 11,然后是 1。
- 向下,向下——得到 11 个,然后 11 个。
那么如何用 Python 代码实现这一点呢?受过传统训练的计算机科学家可能会创建一个树类,然后递归地遍历它。但那是周日晚上,我不是递归的大师,所以我用快速而肮脏的方法遍历了我的树。
遍历树
下面是我的代码。我会一步一步地教你。
第一个块是主要功能。它将 ace 的数量作为一个整数变量 num_aces,创建一个名为 temp_list 的列表,然后将该列表传递给一个助手函数 get_ace_values,该函数产生最终结果。在我传递给 get_ace_values 的列表变量 temp_list 中,每个 ace 都表示为[1,11] —所以如果有三个 ace,temp_list = [[1,11],[1,11],[1,11]]。
# Convert num_aces, an int to a list of lists
# For example if num_aces=2, the output should be [[1,11],[1,11]]
# I require this format for the get_ace_values functiondef ace_values(num_aces):
temp_list = []
for i in range(num_aces):
temp_list.append([1,11])
return get_ace_values(temp_list)
现在该迭代了。我没有递归地遍历树,而是将树重新想象成一个数组,其中每一行对应于树的一次端到端遍历。这是三张 a 的情况:
[[ 1\. 1\. 1.] # up, up, up
[ 1\. 1\. 11.] # up, up, down
[ 1\. 11\. 1.] # up, down, up
[ 1\. 11\. 11.] # up, down, down
[11\. 1\. 1.] # down, up, up
[11\. 1\. 11.] # down, up, down
[11\. 11\. 1.] # down, down, up
[11\. 11\. 11.]] # down, down, down
你看到模式了吗?首先,遍历树有 2 = 8 种可能的方式(因为有三个 ace)。在我们的数组的第一列中,数字每四个元素切换一次(从 1 到 11)。在第二列中,它们每两个交换一次。在最后一栏,他们转换了所有元素。
下面是我的 get_ace_values 函数的代码。这肯定不是最优雅的解决方案。我在下面的项目符号中解释了它是如何工作的。
def get_ace_values(temp_list):
sum_array = np.zeros((2**len(temp_list), len(temp_list)))
# This loop gets the permutations
for i in range(len(temp_list)):
n = len(temp_list) - i
half_len = int(2**n * 0.5)
for rep in range(int(sum_array.shape[0]/half_len/2)):
sum_array[rep*2**n : rep*2**n+half_len, i]=1
sum_array[rep*2**n+half_len : rep*2**n+half_len*2, i]=11
return [int(s) for s in np.sum(sum_array, axis=1)]
- 第一个 for 循环运行的次数等于我们拥有的 ace 数 temp _ list 的长度等于我们拥有的 ace 数。for 循环的每一次运行都会产生 sum_array 的一列,即我上面描述的数组。
- 变量 n 只是从 ace 的数量开始向下计数,一直到 1。例如,如果有三个 ace,n 将从 3 开始,然后在第二次循环中减少到 2,最后在 1 结束。
- 变量 half_len 告诉我们在切换到打印 11 之前连续打印 1 的次数(相同的次数)。如果你还记得我在上面给你看的 sum_array 矩阵,在第一列,我们打印了四个 1 后面跟着四个 11。因此,对于 for 循环的第一次运行(对于三个 ace 的情况),half_len 等于 2 * 0.5 = 4。在第二列中,我们每两个元素交换一次,因此 half_len 等于 2 * 0.5 = 2。
- 对于三个 ace 的情况,第二个 For 循环(嵌套循环)在外部 for 循环的第一次运行时运行一次,在外部循环的第二次运行时运行两次,最后在外部循环的最后一次运行时运行四次。这个嵌套循环用于在我们需要的地方打印 1 和 11。
THREE ACE CASEIn the first run of the outer loop, since half_len=4, the nested for loop runs once (8/half_len/2 = 1) and prints four 1s followed by four 11s onto sum_array:
[[ 1\. 0\. 0.]
[ 1\. 0\. 0.]
[ 1\. 0\. 0.]
[ 1\. 0\. 0.]
[11\. 0\. 0.]
[11\. 0\. 0.]
[11\. 0\. 0.]
[11\. 0\. 0.]]In the second run of the outer loop, since half_len=2, the nested for loop runs twice (8/half_len/2 = 2), each time printing two 1s followed by two 11s onto sum_array:
[[ 1\. 1\. 0.]
[ 1\. 1\. 0.]
[ 1\. 11\. 0.]
[ 1\. 11\. 0.]
[11\. 1\. 0.]
[11\. 1\. 0.]
[11\. 11\. 0.]
[11\. 11\. 0.]]In the third run of the outer loop, since half_len=1, the nested for loop runs four times (8/half_len/2 = 4), each time printing a 1 followed by a 11 onto sum_array:
[[ 1\. 1\. 1.]
[ 1\. 1\. 11.]
[ 1\. 11\. 1.]
[ 1\. 11\. 11.]
[11\. 1\. 1.]
[11\. 1\. 11.]
[11\. 11\. 1.]
[11\. 11\. 11.]]
- 差不多了 sum _ array 的每一行现在都可以用来表示我们的树的一个端到端遍历,这意味着每一行都是一个排列。所以我们要做的就是取 sum_array 中每行的和,得到所有可能的 ace 值。
让我们为三种 ace 情况运行 ace_values:
Running:
ace_values(3)Produces:
[3, 13, 13, 23, 13, 23, 23, 33]Taking the set of this:
set(ace_values(3))Produces what we want:
{3, 13, 23, 33}
我很喜欢编码,但是我还有很多要学的,所以我会经常发表这样的散漫的文章。请原谅我。
干杯,下次再见!
我最近的一些帖子,希望你能看看
面向数据科学的 python——Plotly 数据可视化指南
现在是 2020 年,是时候停止使用 Matplotlib 和 Seaborn 了
Photo by Carlos Muza on Unsplash
问候我的数据从业者同事们,欢迎回到我的数据之旅的另一集。本周我们将讨论数据的可视化,它们有多重要,以及你应该使用什么样的 python 库来制作它们。所以上车吧,放松,享受旅程。
如果你像我一样是一名数据从业者,你应该经历过需要向别人解释你的数据的情况。你需要讲一个故事,表达你的观点,说服你的同事、主管甚至你的首席执行官。现在,想象你试图解释不到 20%的男性在泰坦尼克号数据集中幸存。
会是什么样子?
Male Survivability (Titanic Dataset)
正如你所看到的,可视化在解释你的数据方面发挥了巨大的作用。在屏幕上显示数字并不适用于某些人。视觉效果的确与众不同。
可视化帮助数据科学家理解和发现数据中隐藏的故事。在一个实例中,一个简单的直方图可以告诉你比你自己试图找出分布更多的信息。
这是泰坦尼克号数据集的票价分布。
Distribution for Fares (Titanic Dataset)
直截了当地绘制出来告诉我们,我们的大多数客户的票价都在 100 美元以下。这是很好的信息,但是它没有告诉我们的全部情况。
想象给了你一些你不知道的问题的答案。本·施奈德曼
水流
当数据可视化首次成为一件事情时,数据从业者在与熊猫一起探索数据时绘制图表。使这成为可能的库叫做 Matplotlib,它是一个好的库,因为它是:
- 使用方便
- 快的
- 与熊猫和谐相处
然而,使用时间足够长的人会觉得它很乏味。甚至 Matplotlib 的官方功能也声明:
Matplotlib 主要用于基本绘图。— Matplotlib
因此,想要一个由更多绘图模式、选项和更简单语法组成的更有趣的库的数据从业者蜂拥至 Seaborn 库。在那个时候,Seaborn 是很多人的首选。这是我们刚刚绘制的直方图的一张 Seaborn 图。
Distribution for Fares (Titanic Dataset) in Seaborn
Seaborn 图书馆还提供了数量惊人的情节,从 Hexbin 情节到 Violin 情节,那种你从未想过你会需要的情节。这里有一个他们提供的情节类型的简要预览。
Seaborn’s Official Gallery
然而,仍然有一个问题。所有这些库都提供静态图。这些图只能告诉你它们在屏幕上显示的内容。你不能更深入地研究这些图,将鼠标悬停在点上来查找信息或添加过滤器。
能够执行此类功能的绘图被命名为
交互式可视化。
互动可视化很受欢迎,因为它可以在你呈现的情节上添加大量信息,释放可能性,让你看起来10 倍 酷。很难用语言表达,让我们想象一下我想告诉你的事情。
这是泰坦尼克号数据集中同样的票价分布图。
Distribution of Fares (Titanic Dataset)
请注意,我们可以将鼠标悬停在直方图上,了解我们所指的分布
(男性或女性),了解我们所悬停的值,放大和缩小以深入了解这些值,以及过滤男性或女性。你已经可以想象这是多么强大,这将如何有助于你用数据讲述故事。
使这成为可能的库被称为通俗地说就是。
Plotly
Plotly
Plotly 是用于交互式数据可视化的 Python 库。Plotly 允许你绘制比 Matplotlib 或 Seaborn 更好的交互式图形。
Plotly 绘制什么样的图形?
- 所有 Matplotlib 和 Seaborn 图表
- 统计图表,包括但不限于平行分类和概率树图
- 你从未想到的科学图表从网络图到雷达图
- 财务图表对时间序列分析有用,例子包括蜡烛图、漏斗图和子弹图
- 地质图和允许你与之互动的三维绘图
Plotly Examples from Plotly Announcement
为什么 Plotly 这么受欢迎?
-
互动剧情
-
比 Matplotlib/Seaborn 漂亮(有待商榷?)
-
提供更详细的可视化效果,有助于探索、理解和交流您的数据
-
为您的绘图提供最大化定制,包括添加滑块和过滤器的
-
更加清晰易懂的代码库
-
由一家名为 Plotly 的公司支持,该公司开发基于网络的交互式可视化和网络应用程序
我如何安装 Plotly?
安装 Python,
pip install plotly
pip install cufflinks
先决条件
在本指南中,我们将与熊猫一起工作。因此,需要对熊猫的基本知识有一个扎实的了解。
这里有一篇我写的关于熊猫的文章让你快速了解。
不管它带来多少好处,人们倾向于避免它,因为:
- 令人困惑的代码的语法
- 进口商品可能会吓跑一些人
- 被可用的工具淹没(袖扣和仪表板)
- 缺乏一个好的指南来策划(这就是为什么我做了这个)
不要害怕,我会牵着你的手度过这段艰难的时光。抓起一杯咖啡,坐在一个舒适的位置,准备做一些代码。
进口
在本指南中,我们将使用 Jupyter 笔记本。让我们把这一个做好。
**from plotly.offline import init_notebook_mode,iplot
import plotly.graph_objects as go
import cufflinks as cf
init_notebook_mode(connected=True)**
由于 Plotly 的操作方式,它会将您的绘图保存到一个单独的 html 文件中,并直接在不同的窗口中打开它。当您在控制台/终端中运行代码时,就会发生这种情况。因此,我们使用 plotly.offline、iplot 和 init_notebook 模式来帮助我们在 Jupyter 笔记本本身上绘制图形。****
在本指南中,我将重点介绍原始的 plotly 语法,因为它为您的图形提供了最大限度的定制。 Plotly Express 和 Cufflinks 为简单的代码绘制提供了更好的选择,但是它们没有像原始语法那样提供很多工具。
定义需要绘制的内容
在策划任何事情之前,你需要知道你想策划什么。问自己这样的问题:
- 你想传达什么样的信息?
- 您是在绘制数值还是分类值呢?
- 你想画出多少变量?
回答完其中的一些问题,你就可以开始规划你的剧情了。
我们将使用经典的 泰坦尼克号数据集 ,从我写的 熊猫指南 继续我们的数据探索。
导入数据集
**df = pd.read_csv(filepath)**
Titanic Dataset
同样,这个数据集的主要目的是研究什么是影响泰坦尼克号上人员生存能力的因素。
我首先想到的是显示泰坦尼克号失事中有多少乘客幸存。因此,可视化幸存的柱本身将是一个好的开始。****
数据、布局和图形
在 Plotly 中,我们定义要绘制的图形对象。绘图所需的 3 个主要参数是数据、布局和图形参数。
因此,我们需要用一种清晰简洁的方式来定义它们,这样其他人就能理解我们试图绘制的内容。
由于我们是单独绘制幸存的列的,我们的数据将是一个****
圆形分格统计图表
#labels
lab = df["Survived"].value_counts().keys().tolist()
#values
val = df["Survived"].value_counts().values.tolist()trace = go.Pie(labels=lab,
values=val,
marker=dict(colors=['red']),
# Seting values to
hoverinfo="value"
)data = [trace]
Plotly 的饼状图带入必需的参数**,默认为标签和值。因此,我们将标签定义为幸存列的唯一值,在本例中为值 1 和 0。我们试图显示的值是这些唯一值的计数。然后,我们将数据定义为一个包含我们刚刚定义的饼图对象的列表。**
布局 布局顾名思义,就是你的情节的布局。
在这里,您可以定义绘图标题,x 和 y 轴标题,显示图例,激活过滤器/滑块以及更多对图表的定制。由于我们只为单个列绘制了一个饼图,所以不要把它做得太花哨。****
layout = go.Layout(title="Survived Distribution")
我们正在创建一个布局** 对象,这里只包含标题参数。**
****图
图图是你想要绘制的,它默认接受我们已经定义好的数据和布局参数。
fig = go.Figure(data = data,layout = layout)
然后,我们可以通过用 Plotly 按字面意义绘制它来显示这个图。
iplot(fig)
Pie Chart
瞧,你已经成功地绘制了一个交互图**。请注意,当悬停在每个部分上时,我们能够看到实际值。这在以干净专业的方式呈现可视化效果时非常有用。尝试为性别和p 类别列绘制一个饼图。**
接下来,让我们探索一些数字列,它们是年龄和费用列。当单独绘制数字列时,我们会想到一个分布图。在这种情况下,我将使用直方图**。**
柱状图
# defining data
trace = go.Histogram(x=df['Age'],nbinsx=40,histnorm='percent')
data = [trace]# defining layout
layout = go.Layout(title="Age Distribution")# defining figure and plotting
fig = go.Figure(data = data,layout = layout)
iplot(fig)
Histogram
完美。我们可以清楚地看到乘客的年龄在这里是如何分布的。
注意,我们可以调整直方图的两个有用参数,它们是:
- Histnorm —绘制直方图所依据的值,它被设置为“百分比”,以便我们显示对分布有贡献的条柱的百分比。如果留空,默认情况下显示箱子的数量。
- nbinsx —要分配到的值的箱数。箱数越多,分布越详细。
酷毙了。到目前为止,我们只绘制了一个变量的图表。现在让我们通过绘制这些变量之间的相互关系来研究它们之间的关系。
让我们找出我们的年龄和票价列之间的关系。这将有助于回答这样的问题——老年人是否倾向于购买更贵的机票?
当绘制两个数值时,
散点图将是一个很好的起点。
散点图
#defining data
trace = go.Scatter(x = df['Age'],y=df['Fare'],text = df['Survived'],mode='markers')data=[trace]#defining layout
layout = go.Layout(title='Fare Vs Age Scatter Plot',xaxis=dict(title='Age'),yaxis=dict(title='Fare'),hovermode='closest')#defining figure and plotting
figure = go.Figure(data=data,layout=layout)
iplot(figure)
Scatter Plot
请注意,我在该图中添加了一些微妙的特征,即 x 和 y 轴标题以及悬停在该点上时显示的值**。您可以通过更改代码中的文本参数来自定义显示 值。**
观察这个情节,我们并没有真正看到列之间的线性关系。票价往往会触及 300 英镑以下的价格上限。我们还观察到,老年人也买便宜的机票。除此之外,单纯依靠这个情节,我们真的说不出太多。
我们可以通过查看 Pclass 列进一步研究这个问题,这是乘客的机票等级。通过绘制每个阶层的平均年龄和费用,我们可以看到这里是否有联系。
条形图
让我们绘制一个显示这些信息的条形图。对于每个 Pclass,我们希望显示该 Pclass 中的平均年龄和费用**。如果你注意到了,我们在这里开始处理多个变量,确切地说是 3 个。**
为了简单起见,我将在我们的条形图中以色标的形式绘制 x 轴上的 Pclass,y 轴上的平均年龄和平均票价。因此,我们需要首先计算每个等级的平均年龄和票价。
y=[]
fare = []
for i in list(df['Pclass'].unique()):
result = df[df['Pclass']==i]['Age'].mean()
fares = df[df['Pclass']==i]['Fare'].mean()
y.append(result)
fare.append(fares)
之后,我们可以绘制图表。
#defining data
trace = go.Bar(x = list(df['Pclass'].unique()),y=y,marker=dict(color=fare,colorscale='Viridis',showscale=True),text = fare)
data=[trace]#defining layout
layout = go.Layout(title='Age/Fare vs Pclass Bar Chart',xaxis=dict(title='Pclass'),yaxis=dict(title='Age'),hovermode='closest')#defining figure and plotting
figure = go.Figure(data=data,layout=layout)
iplot(figure)
Bar Chart
我们在这里添加了两个新参数,它们是:
- 颜色—与色标相关的值
- 色标-显示数值大小的色标类型
酷毙了。将鼠标悬停在条形上方,我们可以看到每个等级的平均年龄和票价,更不用说定义票价的清晰色标了。条形图清楚地显示了年龄和票价随着 Pclass 的增加而降低。
我们也可以通过绘制每个 Pclass 的年龄和票价的分布来证实这一点。这将为我们提供每类数据的清晰图像,而不是平均值。为此,我们将使用 distplot。
分布图
分布图类似于直方图,但它们在底部包括另一个计数图,以便更好地显示分布。
我们必须为分布图导入一个额外的库。
import plotly.figure_factory as ff
让我们分别根据年龄和票价
绘制两张图表。
#defining data
a = df[df['Pclass']==1]['Fare']
b = df[df['Pclass']==2]['Fare']
c = df[df['Pclass']==3]['Fare']
hist_data=[a,b,c]
group_labels=['1','2','3']#defining fig and plotting
fig = ff.create_distplot(hist_data,group_labels,bin_size=
[1,1,1],show_curve=False)
fig.update_layout(title_text='Distribution for Fares')
iplot(fig)
Distribution of Fares
a = df[df['Pclass']==1]['Age']
b = df[df['Pclass']==2]['Age']
c = df[df['Pclass']==3]['Age']
hist_data=[a,b,c]
group_labels=['1','2','3']
fig = ff.create_distplot(hist_data,group_labels,bin_size=[1,1,1],show_curve=False)
fig.update_layout(title_text='Distribution for Age')
iplot(fig)
Distribution of Age
两张分布图都清楚地表明,较低的社会阶层
与较高的年龄和较高的票价相关。通俗地说,就是头等舱机票价格更高,年纪大的人更倾向于购买头等舱机票。
得出这个结论后,我们想知道生存能力与这些变量有什么关系。我们可以用气泡图来绘制针对他们的生存能力图。气泡图允许可视化多达 4 个变量,这可以帮助我们传达我们的观点。
气泡图
气泡图类似于散点图,但它们有一个额外的大小参数来定义每个点的半径。
#defining data
data=[
go.Scatter(x = df['Age'],y=df['Fare'],
text=df['Pclass'],
mode='markers',
marker=dict(size=df['Pclass']*15, color=df['Survived'],showscale=True),
)]#defining layout
layout = go.Layout(title='Fare vs Age with Survivability and Pclass',xaxis=dict(title='Age'),yaxis=dict(title='Fare'),hovermode='closest')#defining figure and plotting
figure = go.Figure(data=data,layout=layout)
iplot(figure)
Bubble Plot
从泡沫图中,我们可以看出:
- 更高的年龄不会导致更高的票价
- 所有高于 50 英镑的票价都被视为头等票
- 如果所有其他变量不变,1 级具有更高的生存能力
- 如果所有其他变量不变,年龄越高,存活率越低
这里是本文中所有可视化的完整代码。
此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…
github.com](https://github.com/nickefy/data-visualization-with-plotly/blob/master/A%20Guide%20to%20Data%20Visualization%20with%20Plotly.ipynb)**
恭喜
Basic Charts from Plotly
通过和我一起完成这个数据探索课程,你已经从 Plotly 学会了大部分的基本图表。仅仅依靠基本图表就能得出的结论是不是很神奇?现在,你应该意识到强大的可视化在探索和理解你的数据中是多么的重要。
在你走之前
我们还没有完成对这个数据集的数据探索和可视化。我正在做更多的高级可视化文章,比如添加滑块/过滤器等等,你绝对可以期待更多这样的帖子。与此同时,请随意查看我的其他文章,以暂时满足您对数据的渴望。
最后,我总是会引用一句话。
现在是 2020 年,停止使用 Matplotlib 和 Seaborn ,提升你的可视化。
订阅我的时事通讯,保持联系。
也可以通过 我的链接 注册中等会员来支持我。你将能够从我和其他不可思议的作家那里读到无限量的故事!
我正在撰写更多关于数据行业的故事、文章和指南。你绝对可以期待更多这样的帖子。与此同时,可以随时查看我的其他 文章 来暂时填补你对数据的饥渴。
感谢 阅读!如果你想与我取得联系,请随时通过 nickmydata@gmail.com 联系我或我的 LinkedIn 个人资料 。您也可以在我的Github中查看之前的撰写代码。
用于数据科学的 Python 使用 Plotly 进行数据可视化的高级指南
如何在 Plotly 中添加和自定义滑块、下拉菜单和按钮
嗨,读者,如果你像我一样,你会每天都想学习新的东西。我可以帮忙。这是我每周写的另一篇关于数据行业的文章。本周,我们将再次谈论数据可视化。
找个舒服的地方,喝杯咖啡,准备写点代码。
上周,我们谈到了数据可视化的重要性。 我们了解到 Plotly 与经典的 Matplotlib 和 Seaborn 相比,在解释和探索数据方面非常有用。我们还学会了用 Plotly 绘制基本的 可视化,如条形图、饼状图和气泡图。
我们在我写的第一篇 文章 中谈到过。
[## 面向数据科学的 python——Plotly 数据可视化指南
现在是 2020 年,是时候停止使用 Matplotlib 和 Seaborn 了
towardsdatascience.com](/python-for-data-science-a-guide-to-data-visualization-with-plotly-969a59997d0c)
在我们接触了 Plotly 之后,是时候通过使用它提供的交互式工具来挖掘它的真正潜力了。当我们用 Plotly 可视化数据时,我们能够添加某些工具来允许我们定制可视化体验。在向企业主展示数据时,这一点可能是至关重要的,因为它能够更清晰地传达你的观点。
这里有一个关于 泰坦尼克号数据集 ,
的例子,说我们想同时显示女性和男性的票价分布以及能够分别显示它们。我们可以为此添加一个下拉菜单,Plotly 会为我们完成剩下的工作。****
Distribution of Fares by Gender
通过使用 plotly,我们可以自定义交互地在图表上显示什么和不显示什么。我们通过添加下拉框、滑块、按钮和其他选项来做到这一点。这里的男性和女性选项可能看起来很简单,但是我们将在本文中看到它是多么有用。
在本指南中,我将全面介绍如何添加和定制你自己的下拉菜单、滑块和按钮来改善你的视觉效果。
先决条件
显然,在本指南中,我们将大量使用 Plotly。
因此,请确保你在继续阅读本进阶指南之前,对有一个坚实的理解。你可以在这里参考我写的关于的文章。
通过与 Plotly 一起工作,你应该也能轻松地与熊猫一起工作。
真巧。我碰巧也写了一本熊猫指南。请务必回忆一下。
10 分钟内完成数据探索指南
towardsdatascience.com](/python-for-data-science-basics-of-pandas-5f8d9680617e)
Plotly,熊猫等。来吧,你知道我有你。****
进口
像往常一样,我们将使用 Jupyter 笔记本。
**#all plotly
from plotly.offline import init_notebook_mode,iplot
import plotly.graph_objects as go
import cufflinks as cf
init_notebook_mode(connected=True)#others
import pandas as pd
import numpy as np**
导入数据集
**df = pd.read_csv(filepath)**
下拉菜单
让我们使用我在本文中第一次展示的选项,
下拉菜单。
Dropdown Menu from Plotly
如果您想在保留地块上的空间的同时允许一系列选项,下拉菜单非常有用。我们不想让那些看你图表的人被一堆选项淹没。因此,我们将它们隐藏在下拉列表中,如果他们愿意,允许他们访问这些选项。
如果你还没有读过我的关于 Plotly 基础的文章,
我们需要在 Plotly 中定义 3 个重要参数。
数据、布局和图参数。
我们在绘图中添加下拉菜单的方法是在 Plotly 的布局参数中添加该命令。
**layout=go.Layout(updatemenus=list([dict(buttons= list_updatemenus)]))**
这将为我们设置下拉菜单。然而,我们需要定义在下拉菜单上显示什么,以及在选择这些选项时要应用的更改。我们可以通过定义 list_updatemenus 参数来实现以上所有功能。
特别说明:plot ly 中的下拉菜单不仅可以改变数据,还可以改变你的布局和播放动画。在本文中,我们将只讨论与数据的交互。你可以在这里做更多的研究,也许有一天我会写这个话题。嗯(表示踌躇等)…精神食粮。
Dropdown Menu by Plotlyz
回到手头的事情, list_updatemenus 是一个字典列表。
对于每个字典,下拉菜单中都会生成一个选项。
我们在每个字典中定义了这些选项的功能。
当我这么说的时候,听起来很混乱,
,但是当你用代码来处理它的时候,它实际上要简单得多。
我们开始吧。
对于 list_updatemenus、 中的每一个字典,我们可以把这个字典的每一个都称为一个选项。 对于每个选项,我们至少需要定义 3 个参数:
- 标签(字符串)—要在下拉菜单上显示的文本
- 方法(字符串)-选择选项时要执行的更新方法
- args (list) —包括将改变显示数据的参数
对于 args 参数,我们应该在列表中至少有两个参数:
- 可见(列表)-确定应该和不应该显示哪些数据
- 标题(字符串)-显示为图形标题的文本
这里有一个图表可以帮助你理解正在发生的事情。
Dropdown Menu Simplified
可见参数
Args 中的‘Visible’定义了我们的图中显示的内容。
是我们在 plotly 中定义的数据参数对应的布尔值列表。****
同样,我们的数据参数是我们为绘制图表而定义的图表对象列表。通过定义 visible 参数,我们可以选择交互显示哪个/哪些图形对象。
这里有个例子,假设我们的数据是
**data= [
go.Histogram(x=option1,name='option1'),
go.Histogram(x=option2,name='option2',
go.Histogram(x=option3,name='option3')
]**
通过使用这里的 visible 参数,我们可以选择只显示列表中图形对象的任意组合。
**#Show first graph object
{'visible':[True, False, False]}#Show second graph object
{'visible':[False, True, False]}#Show first and third graph object
{'visible':[True, False, True]}**
既然你已经理解了每样东西的含义,这里有一个模板来定义你的下拉菜单。
**list_updatemenus =
[{'label': 'Option 1',
'method': 'update',
'args': [{'visible': [True, False, False]}, {'title': 'Title is Option 1'}]},
{'label': 'Option 2',
'method': 'update',
'args': [{'visible': [False, True, False]}, {'title': 'Title is Option 2'}]},
{'label': 'Option 3',
'method': 'update',
'args': [{'visible': [False, False, True]}, {'title': 'Title is Option 3'}]}]layout=go.Layout(title = 'default title',
updatemenus=list([dict(buttons= list_updatemenus)]))**
这里有一个关于泰坦尼克号数据集的例子。
我们想按等级和性别显示票价的分布。
我们可以通过以下方式实现:
**#defining list_updatemenus
list_updatemenus = [{'label': 'Survived',
'method': 'update',
'args': [{'visible': [False, False, False, True, True, True]}, {'title': 'Distribution of Age for Survived Passengers'}]},
{'label': 'Non Survived',
'method': 'update',
'args': [{'visible': [True, True, True, False, False, False]}, {'title': 'Distribution of Age for Non-Survived Passengers'}]}]#defining all graph objects
x_pclass3 = df[df['Pclass']==3]['Fare']
x_pclass1 = df[df['Pclass']==1]['Fare']
x_pclass2 = df[df['Pclass']==2]['Fare']
x_male = df[df['Sex']=='male']['Fare']
x_female = df[df['Sex']=='female']['Fare']#defining data
data=[go.Histogram(x=x_pclass3,name='3rd Class'),go.Histogram(x=x_pclass1,name='1st Class',opacity = .5,nbinsx=60),go.Histogram(x=x_pclass2,name='2nd Class',opacity = .5),go.Histogram(x=x_male,name='Male',opacity = .5),go.Histogram(x=x_female,name='female',opacity = .5)]#defining layout
layout=go.Layout(title='Distribution of Fares by Pclass and Gender',updatemenus=list([dict(buttons= list_updatemenus)]),barmode='overlay')#defining figure and plotting
fig = go.Figure(data,layout)
iplot(fig)**
Distribution of Fares by Gender and Pclass
从这个图中,我们可以与它交互来显示按性别或阶级的票价分布。然后我们可以通过点击图例分别显示每个 p 类或性别或集体显示。现在,你应该意识到这有多强大了。****
在这个例子中,我们只使用直方图。您也可以选择其他图,以不同的方式可视化相同的指标。在这一点上,如何呈现数据完全取决于你的想象。
自定义按钮
Custom Buttons from Plotly
自定义按钮的作用与下拉菜单相同。唯一不同的是,自定义按钮将所有选项提前显示在图上,让全世界都能看到。如果你想让你的观众提前知道你所有的选择,这可能会也可能不会帮助他们更好地理解你试图展示的东西。****
添加自定义按钮的语法也与下拉菜单非常相似。
唯一不同的是你在布局中添加了“type = buttons”。
**layout=go.Layout(updatemenus=list([dict(buttons= list_updatemenus), type = buttons]))**
差不多就是这样。让我们来看另一个例子。
对于这个例子,我们试图通过 Pclass 显示幸存和非幸存乘客的年龄分布。
**#defining list_updatemenus
list_updatemenus = [{'label': 'Survived',
'method': 'update',
'args': [{'visible': [False, False, False, True, True, True]}, {'title': 'Distribution of Fares by Pclass'}]},
{'label': 'Non Survived',
'method': 'update',
'args': [{'visible': [True, True, True, False, False, False]}, {'title': 'Distribution of Fares by Gender'}]}]#defining graph objects
x_pclass3_nonsurvived = df[df['Pclass']==3][df['Survived']==0]['Age']
x_pclass1_nonsurvived = df[df['Pclass']==1][df['Survived']==0]['Age']
x_pclass2_nonsurvived = df[df['Pclass']==2][df['Survived']==0]['Age']
x_pclass3_survived = df[df['Pclass']==3][df['Survived']==1]['Age']
x_pclass1_survived = df[df['Pclass']==1][df['Survived']==1]['Age']
x_pclass2_survived = df[df['Pclass']==2][df['Survived']==1]['Age']#defining data
data=[go.Histogram(x=x_pclass3_nonsurvived,name='Died 3rd Class',nbinsx=60),go.Histogram(x=x_pclass1_nonsurvived,name='Died 1st Class',opacity = .5,nbinsx=60),go.Histogram(x=x_pclass2_nonsurvived,name='Died 2nd Class',opacity = .5,nbinsx=60),go.Histogram(x=x_pclass3_survived,name='Survived 3rd Class',nbinsx=60),go.Histogram(x=x_pclass1_survived,name='Survived 1st Class',opacity = .5,nbinsx=60),go.Histogram(x=x_pclass2_survived,name='Survived 2nd Class',opacity = .5,nbinsx=60)]#defining layout
layout=go.Layout(title='Distribution of Age by Pclass',updatemenus=list([dict(buttons= list_updatemenus,type = 'buttons')]),barmode='overlay')#defining layout and plotting
fig = go.Figure(data,layout)
iplot(fig)**
观察剧情,我们可以看到大多数非幸存者购买了泰坦尼克号上的3 级T7 级。这些第三类非幸存者的年龄大多在 15 和 35 之间。这让我相信,Pclass 列肯定在决定幸存者是否幸存方面发挥了作用。
有了自定义按钮,对观众来说更加明显你在过滤幸存和非幸存的乘客。在某些情况下,这将使你的演示看起来更专业,更容易理解。
滑块
Sliders from Plotly
虽然按钮和下拉菜单擅长显示不同的图表,但我发现滑块擅长在改变 某些变量的值时显示图表。如果所述变量是连续的数字变量,则更加明显。年龄可以是一个完美的例子。
滑块的工作方式与下拉菜单和按钮相同。不同之处在于,滑块允许你在与滑块交互时显示大量的选项。滑块本身也给人一种增加和减少某个值的错觉,但事实可能并非如此。
我们可以像使用下拉菜单和按钮一样使用滑块,通过从不同角度切片数据来显示不同类型的图表。然而,我更喜欢展示某个情节,同时能够操纵一个变量来更好地讲述一个故事。
就像下拉菜单和按钮一样,我们在绘图中添加滑块的方式是在我们的布局中添加一个简单的参数。
**layout=go.Layout(
sliders=sliders
)**
我们通过定义滑块和步骤参数来定义在滑块上显示的内容和应用的更改,就像我们如何定义下拉菜单的 list_updatemenus 一样。
类似地,滑块参数是一个字典列表。
对于每个字典,在图上生成一个滑块。
滑块保存定义默认值的参数,如:
- currentvalue(字典)—显示在滑块顶部的文本
- 活动(整数)-要显示的默认步骤
- 步骤(列表)—包括将改变显示数据的参数
步骤参数相当于下拉菜单的 list_updatemenus 。
这是一个字典列表,每个字典在滑块上生成一个选项。我们通过定义以下内容来定义这些选项的功能:
- 标签(字符串)—要在滑块上显示的文本
- 方法(字符串)-选择选项时要执行的更新方法
- args (列表)—包括将改变显示数据的参数
- 可见(列表)—决定哪些数据应该显示,哪些不应该显示
这里有一个图表可以帮助你理解正在发生的事情。
让我们看一个例子来帮助你更好地理解这一点。
为此,我们打算展示随着泰坦尼克号上乘客年龄的增长,生存能力的变化。
在我的脑海中,我正在描绘一个条形图,显示我们操作滑块时幸存的 0 和 1 的计数。既然我们在操纵年龄,我们应该为年龄设置滑块。我们还必须为年龄增长的每一步创建一个图表对象。我们是这样做的。
**# Create figure
fig = go.Figure()# Create Graph Object for every increase of 2 years of Age
for step in np.arange(0, 80, 2):
y=[]
for i in list(df['Survived'].unique()):
result = df[df['Age']<=step][df['Survived']==i]['Survived'].count()
y.append(result)
fig.add_trace(
go.Bar(
visible=False,
x = list(df['Survived'].unique()),
y= y,
name="Age = " + str(step)))**
对于这个代码块,我们为从 0 岁到 80 岁的每两步增长创建一个图形对象(条形图)。因此,我们这里基本上有 40 个步骤和图形对象。滑块将能够有效地浏览这些步骤和图形对象。
接下来,我们定义我们的滑块和步进参数。
**#defining sliders
sliders = [dict(
currentvalue={"prefix": "Age less than "},
active=1,
steps=steps
)]#defining steps
steps = []
for i in range(len(fig.data)):
step = dict(
label = str([i for i in np.arange(0, 80, 2)][i]),
method="restyle",
args=["visible", [False] * len(fig.data)],
)
step["args"][1][i] = True # Toggle i'th trace to "visible"
steps.append(step)**
在这个代码块中,我们创建了一个字典,并将其追加到年龄每增加 2 岁的 steps 参数中,同时包含了对每个步骤所做的所有更改。
最后,我们定义我们的布局并绘制图表。
**#defining layout and plotting
fig.update_layout(
title = 'Change of Survivability with Age',
yaxis=dict(title='Count of Survived'),
sliders=sliders
)
fig.show()**
瞧,多么美丽的情节。我们看到,一旦我们到了 18 岁,非幸存者人数开始超过幸存者人数。我们也可以有把握地说,对于所有 18 岁以下的乘客,他们中的大多数都活了下来。这可能为我们的分析提供有用的信息。
如果你还没明白,滑块在显示数值变化方面非常有效。如果您试图显示相对于时间和时间的数据,它也会发挥巨大的作用。这是一个非常强大的工具,我希望你开始在你的分析中更多地使用它。
下面是我们刚刚在本文中运行的所有内容的完整代码:
**** [## nickefy/advance-用绘图引导数据可视化
此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…
github.com](https://github.com/nickefy/advance-guide-to-data-visualization-with-plotly/blob/master/Advance%20Guide%20to%20Data%20Visualization%20with%20Plotly.ipynb)****
恭喜
Photo by bruce mars on Unsplash
欢欣鼓舞。你坚持到了最后。要接受的东西很多。我明白了。
在本指南中,您已经学习了 Plotly 的 3 个主要交互工具,它们是:
- 下拉菜单
- 小跟班
- 滑块
这些工具在试图理解数据集、执行有价值的分析和向利益相关者展示时,肯定会给你带来优势。
在你走之前
我们的数据之旅还没有结束。我正在撰写更多关于数据行业的故事、文章和指南。你绝对可以期待更多这样的帖子。与此同时,请随意查看我的其他文章,以暂时满足您对数据的渴望。
现在继续吧,我的朋友们,向世界展示我们数据从业者有多强大。
和往常一样,我以一句名言结束。
如果没有大数据,你会又瞎又聋,还在高速公路上。—杰弗里·摩尔
订阅我的时事通讯,保持联系。
也可以通过 我的链接 注册中等会员来支持我。你将能够从我和其他不可思议的作家那里读到无限量的故事!
我正在撰写更多关于数据行业的故事、文章和指南。你绝对可以期待更多这样的帖子。与此同时,可以随时查看我的其他 文章 来暂时填补你对数据的饥渴。
感谢 阅读!如果你想与我取得联系,请随时联系我在 nickmydata@gmail.com 或我的 LinkedIn 个人资料 。也可以在我的Github中查看之前的撰写代码。
用于数据科学的 Python 熊猫指南
10 分钟内完成数据探索指南
各位数据从业者好。对我来说,这是忙碌的一周,但我回来了。
首先,我想亲自感谢那些从第一天起就决定追随我的人。我最近达到了 100 个追随者的大关。这并不多,但当我的内容被证明为某个随机的男孩/女孩提供了价值时,它对我来说就意味着整个世界。我开始写作是为了帮助人们解决他们的一些问题,因为当我面对他们时,我没有太多的资源可以参考。感谢您的关注,我将继续努力为您提供值,就像任何数据科学家都会做的那样。
但是够了,你不是为了那个而来,
你是为了那个数据科学的本质。
你想成为能够对数据执行
惊人技术的人,以获得你需要的东西。
你想成为提供难以置信的洞察力的人,这些洞察力影响
产品经理做出关键决策。
嗯,你来对地方了。进来吧。
我们今天将讨论最重要的
Python 对于 数据科学库。
这是…
*鼓形辊
Photo by chuttersnap on Unsplash
熊猫是的。我相信任何有经验的数据科学家都会同意我的观点。在你所有幻想的机器学习之前,你必须彻底探索、清理和处理你的数据。为此,你需要熊猫。
本指南假设您已经掌握了一些非常基础的 python 知识,并且已经安装了 python。如果没有,就在这里 安装 。我们也在 Jupyter 笔记本 上跑熊猫。确保你有它。我将很快向你介绍熊猫的基本知识。
努力跟上。
熊猫
Pandas 官方代表“Python 数据分析库”,当今数据科学家使用的最重要的 Python 工具。
什么是熊猫,它是如何工作的?
Pandas 是一个开源的 Python 库,它允许用户以极其高效的方式探索、操作和可视化数据。它实际上是 Python 中的 Microsoft Excel。
熊猫为什么这么受欢迎?
- 它很容易阅读和学习
- 它速度极快,功能强大
- 它与其他可视化库集成得很好
- 它同时是黑人、白人和亚洲人
熊猫带什么样的数据?
熊猫可以接受各种各样的数据,最常见的是 csv、excel、sql 甚至一个网页。
我如何安装熊猫?
如果你有蟒蛇,那么
conda install pandas
应该能行。如果没有,请使用
pip install pandas
既然你知道自己会陷入什么样的境地。
让我们直接开始吧。
导入
import pandas as pd
import numpy as np
数据帧和系列
系列像列,而数据帧是你在熊猫中完全展开的表格。你将会经常接触到这两个部分。所以要习惯它们。
从 a: 创建您自己的系列
- 目录
test_list = [100,200,300]
pd.Series(data=test_list)
- 词典
dictionary = {‘a’:100,’b’:200,’c’:300}
pd.Series(data=dictionary)
从 a: 创建您自己的数据框架
- 目录
data = [[‘thomas’, 100], [‘nicholas’, 200], [‘danson’, 300]]
df = pd.DataFrame(data, columns = [‘Name’, ‘Age’])
- 词典
data = {‘Name’:[‘thomas’, ‘nicholas’, ‘danson’, ‘jack’], ‘Age’:[100, 200, 300, 400]}
df = pd.DataFrame(data)
通常,我们不会创建自己的数据框架。取而代之的是,我们通过导入数据到一个数据框架中来研究、操作和可视化熊猫中的数据。
熊猫可以阅读多种格式,但常用的是 csv。这里是熊猫可以读取的文件类型的官方列表。
我们将在这里导入 泰坦尼克号数据集 。
df = pd.read_csv(filepath)
该数据集的主要目的是研究影响泰坦尼克号上人员生存能力的因素。让我们通过研究数据来找出确切的答案。
导入数据后,您想体验一下。下面是一些基本操作:
数据集摘要
df.info()
仅通过这个命令,我们就可以知道行数和列数、列的数据类型以及它们是否存在空值。
每列的唯一值
df.unique()
df.unique()命令允许我们更好地理解每一列的含义。看着幸存的和性列,他们只有 2 个唯一值。这通常意味着它们是分类列,在这种情况下,应该是真或假的幸存和男性或女性的性别。
我们还可以观察到其他分类列,如abowed、 Pclass 等等。我们真的说不清 Pclass 代表什么,让我们多探索一下。
数据选择
在熊猫中选择你想要的数据是极其容易的。
假设我们现在只想查看 Pclass 列。
df[‘Pclass’]
我们观察到,这 3 个唯一值实际上是 1、2 和 3,分别代表 1 级、2 级和 3 级。我们现在明白了。
我们也可以一次选择多个列。
df[[‘Pclass’,’Sex’]]
这个命令对于包含/排除您需要/不需要的列非常有用。
由于我们不需要姓名、乘客 id 和车票,因为它们在决定乘客是否幸存时根本不起作用,所以我们在数据集中排除这些列,这可以通过两种方式完成。
df= df[[‘Survived’,’Pclass’,’Sex’,’Age’,’SibSp’,’Parch’,’Fare’,’Cabin’,’Embarked’]]ordf.drop(['PassengerId', 'Name', 'Ticket'], axis = 1, inplace=True)
inplace=True 参数告诉 Pandas 将您想要做的事情自动分配给原始变量本身,在本例中是 df。
我们也可以通过行选择数据。假设我们想要调查数据集的第 300 到 310 行。
df.iloc[500:511]
它的工作原理就像一个 python 列表,其中区间的第一个数字(500)是包含,区间的最后一个数字(511)是不包含。
条件选择
我们也可以通过数据过滤。假设我们只想观察男性乘客的数据。
df[df['Sex'] == 'male']
命令*df[’ Sex ']= ’ male '*将为每一行返回一个布尔值。在它上面嵌套一个 df[]将返回男性乘客的整个数据集。这就是熊猫的工作方式。
这个命令对于未来可视化数据非常强大。让我们把到目前为止所学的结合起来。
df[[‘Pclass’,’Sex’]][df[‘Sex’] == ‘male’].iloc[500:511]
使用该命令,我们只显示男性乘客的 Pclass 和 Sex 列的第 500 到 510 行。试着使用这些命令,以便更好地使用它们。
聚合函数
既然我们知道如何浏览数据,是时候对其进行一些聚合了。首先,我们可以使用 describe 函数找出数据集的分布、最大值、最小值和有用的统计数据。
df.describe()
请注意,这些数学命令中仅包含数字列。其他列将被自动排除。
我们还可以运行以下命令来返回各自的聚合,请注意,聚合也可以通过条件选择来运行。
df.max()
df[‘Pclass’].min()
df.iloc[100:151].mean()
df.median()
df.count()
df.std()
我们还可以对这些列做一个相关矩阵,找出它们之间的关系。
df.corr()
看起来对乘客生存能力有贡献的前 3 个数字列是票价、p 等级和 Parch ,因为它们相对于幸存列拥有最高的绝对值。
我们还可以查看每列的分布。在表格格式中,更容易解释分类列的分布。
df[‘Sex’].value_counts()
看起来我们的乘客都是男性。
数据清理
如果你已经跟上了,你现在已经对我们的数据有了很好的感觉。你想做一些汇总/可视化来展示你的发现。在那之前,你通常需要在做任何事情之前清理你的数据集。
您的数据集通常包含脏数据,如:
- 空值
- 空值
- 时间戳不正确
- 更多更多
当我们使用命令 df.info()时,我们已经知道是否有任何空值。这里还有一个:
df.isnull().sum()
我们可以看到在年龄、舱和上船列中有空值。当这些特定列中的值为空时,您可以看到这些行的样子。
df[df[‘Age’].isnull()]
由于某种原因,除了年龄和舱室之外的所有其他数据都在这里。
空值的处理完全取决于你。为了简单起见,我们将删除所有包含空值的行。
df.dropna(inplace=True)or#df.dropna(axis=1, inplace=True) to drop columns with null values
如果我们愿意,我们也可以用一个值替换所有的空值。
df[‘Age’].fillna(df[‘Age’].mean())
此命令用年龄列的平均值替换年龄列中的所有空值。在某些情况下,这是处理空值的好方法,因为它不会扰乱值的偏斜度。
分组依据
所以现在你的数据是干净的。我们可以开始通过小组探索数据。假设我们想要找出每个 Pclass 中一名乘客的平均值/最大值/最小值
( 在此处插入数字列)。
df.groupby(‘Pclass’).mean()
or
df.groupby('Pclass')['Age'].mean()
这告诉了我们很多东西。首先,它告诉我们每个等级的平均年龄和票价(T21)。看起来头等舱的票价是最贵的,而且是最老的。有道理。
我们也可以对组进行分层。假设现在我们还想知道每个p 阶级的平均年龄和费用对于男性和女性。
df.groupby([‘Pclass’,’Sex’]).mean()
我们只需通过 GroupBy 函数传递组列表就可以做到这一点。我们可以根据这些复杂的分组开始分析并作出某些假设。我能做的一个观察是,一等舱的女性的平均票价是所有乘客中最高的,他们也有最高的生存能力**。另一方面,三等舱
中雄的平均票价最低,生存能力最低**。****
我想钱确实能拯救生命。
连接和合并
经过一些分析后,我们发现需要在数据中添加一些行/列。我们可以通过连接和合并数据帧轻松做到这一点。
我们通过以下方式添加行:
first_5 = df.head()
last_5 = df[178:]
combined = pd.concat([first_5,last_5], axis = 0)
请注意,连接时,数据帧之间的列必须匹配。它就像 SQL 联合一样工作。
如果我们想通过连接来添加列。我们合并了。
假设我们有一个包含乘客体重和身高的外部数据集。为此,我将为 3 名乘客创建自己的数据集。
data = [[‘Braund, Mr. Owen Harris’, 80, 177.0], [‘Heikkinen, Miss. Laina’, 78, 180.0], [‘Montvila, Rev. Juozas’, 87, 165.0]]
df2 = pd.DataFrame(data, columns = [‘Name’, ‘weight’, ‘height’])
现在,我们想将体重和身高数据添加到我们的泰坦尼克号数据集中。
df3 = pd.merge(df,df2, how=’right’, on=’Name’)
merge 的工作方式与 SQL joins 完全一样,使用 left、right、outer 和 inner 方法。我在这里使用了 right join 来只显示记录了体重和身高的乘客。如果我们使用左连接,结果将显示完整的 titanic 数据集,其中没有身高和体重。
df3 = pd.merge(df,df2, how=’left’, on=’Name’)
数据操作
我们现在进入了更高级的领域,我们希望对数据中的值进行大量的操作。我们可能想要添加我们自己的自定义列,更改值的类型,甚至在数据中实现复杂的函数。
数据类型
这是一个相当直接的操作。有时我们可能想改变数据的类型,为其他函数提供可能性。一个很好的例子是将一个字符串的‘4000’改为一个整数**‘4000’。**
让我们把现在浮点型的重量数据改成整数。
df2[‘weight’].astype(int)
请注意, astype() 函数遍历数据的每一行,并尝试将数据类型更改为您提到的任何类型。因此,每种类型的数据都有一定的规则可循。
例如:
- 数据不能为 null 或空
- 当将浮点数改为整数时,小数必须是. 0 形式
因此, astype() 函数有时会很棘手。
应用功能
应用功能是熊猫最强大的功能之一。
它让你以任何你想要的形式操作数据。以下是方法。
步骤 1:定义一个函数 假设我们想要将 Pclass 重命名为它们的实际名称。
1 =一级
2 =二级
3 =三级
我们首先定义一个函数。
def pclass_name(x):
if x == 1:
x = '1st Class'
if x == 2:
x = '2nd Class'
if x == 3:
x = '3rd Class'
return x
步骤 2:应用函数 然后我们可以将该函数应用于 Pclass 列的每个值。
该过程将通过函数传递 Pclass 列的每条记录。
df3[‘Pclass’] = df3[‘Pclass’].apply(lambda x: pclass_name(x))
Pclass 列的记录现在已经更改。如何处理你的数据完全取决于你的想象力。这里是你发挥创造力的地方。
自定义列
有时,我们希望创建自定义列,以便更好地解释我们的数据。例如,让我们用乘客的身体质量指数创建一个列。
身体质量指数的公式是:
weight(kg) / height²(m)
因此,让我们先把我们的身高值从厘米转换成米和平方的值。我们将使用我们刚刚学过的 apply 函数来实现这一点。
def convert_to_bmi(x):
x = (x/100)**2
return xdf4[‘height’] = df4[‘height’].apply(lambda x: convert_to_bmi(x))
然后,我们创建一个新列,其中的值是体重除以身高。
df4[‘BMI’] = df4[‘weight’]/df4[‘height’]
如果我们有所有乘客的体重指数,我们就可以用身体质量指数得出进一步的结论,但我不会深入研究。你明白了。
定稿和导出
完成所有工作后,您可能希望对列进行排序和重命名。
df3.rename(columns={'BMI':'Body_Mass_Index','PassengerId':'PassengerNo'}, inplace = True)df3 = df3.sort_values('Body_Mass_Index')
我们将身体质量指数重新命名为它的全名,并在这里按身体质量指数排序。
注意,排序后,索引不变,这样信息不会丢失。
最后但同样重要的是,
我们可以将我们的数据导出为多种格式(参考顶部的列表)。
让我们将数据导出为 csv 文件。
df3.to_csv(filepath)
结论
如果你已经走了这么远,给自己一点鼓励。
你已经正式掌握了熊猫的基本知识,
每个数据科学家的必备工具。
今天你所学的知识**😗*
- 创建和导入数据框架
- 数据帧的汇总功能
- 在数据框架中导航
- 价值的聚合
- 清理数据
- 分组依据
- 连接和合并
- 数据操作(应用功能)
- 定稿和导出
让它留在你的脑海里,因为我发誓你以后会经常用到它。
一如既往,我引用一句话作为结束。
你可以有没有信息的数据,但你不能有没有数据的信息——丹尼尔·凯斯·莫兰
订阅我的时事通讯,保持联系。
也可以通过 我的链接 注册一个中等会员来支持我。你将能够从我和其他不可思议的作家那里读到无限量的故事!
我正在撰写更多关于数据行业的故事、文章和指南。你绝对可以期待更多这样的帖子。与此同时,你可以随时查看我的其他 文章 来暂时填补你对数据的渴望。
感谢 阅读!如果你想和我取得联系,请随时通过 nickmydata@gmail.com 联系我或者我的 LinkedIn 个人资料 。也可以在我的Github中查看之前写的代码。