
? 作者:韩信子@ShowMeAI
? 数据分析实战系列:https://www.showmeai.tech/tutorials/40
? 本文地址:https://www.showmeai.tech/article-detail/394
? 声明:版权所有,转载请联系平台与作者并注明出处
? 收藏ShowMeAI查看更多精彩内容
如果你是数据科学家、数据分析师、机器学习工程师,或者任何 python 数据从业者,你一定会高频使用 pandas 这个工具库——它操作简单功能强大,可以很方便完成数据处理、数据分析、数据变换等过程,优雅且便捷。

在本文中,ShowMeAI给大家汇总介绍 21 个 Pandas 的提示和技巧,熟练掌握它们,可以让我们的代码保持整洁高效。
如果我们希望对DataFrame操作,但是不希望改变原始DataFrame,我们可以使用df.copy()制作副本,如下例所示:
import pandas as pd
df = pd.DataFrame({"col1": [1, 2, 3],
"col2": [4, 5, 6]})
df2 = df # Make a copy using =
df2["col1"] = [7, 8, 9]
df # df also changes

# Recrate df
df = pd.DataFrame({"col1": [1, 2, 3],
"col2": [4, 5, 6]})
df3 = df.copy() # Create a copy of df
df3["col1"] = [7, 8, 9]
df # df doesn't change

如果你想获得 Pandas 的一列的计数统计,可以使用groupby和count组合,如果要获取2列或更多列组成的分组的计数,可以使用groupby和size组合。如下所示:
import pandas as pd
df = pd.DataFrame(
{
"col1": ["a", "b", "b", "c", "c", "d"],
"col2": ["S", "S", "M", "L", "L", "L"]
}
)
# get the count of elements in one column
df.groupby(["col1"]).count()

# Get the size of groups of 2+ columns
df.groupby(["col1", "col2"]).size()

大家都知道,我们可以使用value_counts获取列里的取值计数,但是,如果要获取列中某个值的百分比,我们可以添加normalize=True至value_counts参数设置来完成:
import pandas as pd
size = pd.Series(["S", "S", "M", "L", "S", "XL", "S", "M",])
# Get count of each value
size.value_counts()

# Get percentage of each value
size.value_counts(normalize=True)

我们知道可以通过value_counts很方便进行字段取值计数,但是pandas.value_counts()自动忽略缺失值,如果要对缺失值进行计数,要设置参数dropna=False。
import pandas as pd
size = pd.Series(["S", "S", None, "M", "L", "S", None, "XL", "S", "M",])
# Get count of each value, it does not count missing values
size.value_counts()

# pass dropna=False to get missing value count
size.value_counts(dropna=False)

如下例所示,如果我们要对列的取值统计并进行计数过滤,使用count会报错,使用transform是恰当的方法,如下例所示:
import pandas as pd
df = pd.DataFrame({
"type": ["A", "A", "O", "B", "O", "A"],
"value": [5, 3, 2, 1, 7, 3]
})
# Using count will throw an error because the
# Series returned is shorter than the original
# DataFrame
# df.loc[df.groupby("type")["type"].count() > 1]
df.loc[df.groupby("type")["type"].transform("size") > 1]

Markdown 是一种轻量级标记语言,用于使用纯文本编辑器创建格式化文本。我们有时候会想在 markdown 格式中打印一个DataFrame,这时可以使用to_markdown()功能:
import pandas as pd
df = pd.DataFrame({'a': [1, 2, 3, 4],
'b': [5, 6, 7, 8]})
# You can control the printing of the index column
# by using the flag index.
print(df.to_markdown(index=True))

# Ouput markdown with a tabulate option
print(df.to_markdown(tablefmt="grid", index=True))

# To create a markdown file from the dataframe, pass
# the file name as paramters
df.to_markdown("README.md", tablefmt="grid", index=True)

我们经常会使用groupby对数据进行分组并统计每组的聚合统计信息,例如计数、平均值、中位数等。如果您想将分组后的数据字段整合成列表,可以使用lambda x:list(x),如下示例:
import pandas as pd
df = pd.DataFrame(
{
"col1": [1, 2, 3, 4, 3],
"col2": ["a", "a", "b", "b", "c"],
"col3": ["d", "e", "f", "g", "h"],
}
)
# Group by col2
df.groupby(["col2"]).agg(
{
"col1": "mean", # get mean
"col3": lambda x: list(x) # get list
}
)

类似于上例,如果你想把一个DataFrame中某个字符串字段(列)展开为一个列表,然后将列表中的元素拆分成多行,可以使用str.split()和explode()组合,如下例:
import pandas as pd
df = pd.DataFrame({"a": ["1,2", "4,5"],
"b": [11, 13]})
# Turn strings into lists
df.a = df.a.str.split(",")
df

print(df.explode("a", ignore_index=False))

如果要计算两个 DataFrame 的行或列之间的相关性,可以使用.corrwith():
import pandas as pd
df1 = pd.DataFrame({
"a": [1, 2, 3, 4],
"b": [2, 3, 4, 6]
})
df2 = pd.DataFrame({
"a": [1, 2, 3, 3],
"b": [2, 2, 5, 4]
})
df1.corrwith(df2)

交叉制表支持我们分析多个变量之间的关系,可以使用pandas.crosstab()功能:
import pandas as pd
network = [
("Ben", "Smith"),
("Ben", "Patrick"),
("Warren", "Jone"),
("Warren", "Smith"),
("Smith", "Patrick"),
]
# Create a dataframe of the network
friends1 = pd.DataFrame(
network, columns=["person1", "person2"]
)
# Create the order of the columns
friends2 = pd.DataFrame(
network, columns=["person2", "person1"]
)
# Create a symmetric dataframe
friends = pd.concat([friends1, friends2])
# Create a cross tabulation
pd.crosstab(friends.person1, friends.person2)

我们可以使用df.query()功能进行数据过滤,它支持以简洁的方式叠加很多个条件。
import pandas as pd
df = pd.DataFrame({
"fruit": ["apple", "orange", "grape", "grape"],
"price": [4, 5, 6, 7]
})
# Filter using brackets
df[(df.price > 4) & (df.fruit == "grape")]

# Filter using query
df.query("price > 4 & fruit == 'grape'")

如果要将 DataFrame 从宽表格式转换为长表格式,可以使用pandas.melt()。
pandas.melt()将多列(“Aldi”、“Walmart”、“Costco”)转换为一列(“store”)的值。import pandas as pd
df = pd.DataFrame({
"fruit": ["apple", "orange"],
"Aldi": [4, 5],
"Walmart": [6, 7],
"Costco": [1, 2]
})
df

# Turn Aldi, Walmart, Costco into values of "store"
df.melt(id_vars=["fruit"],
value_vars=["Aldi", "Walmart", "Costco"],
var_name='store')

我们经常会使用分组聚合的功能,如果要为聚合分配新名称,可以使用name = (column, agg_method)方法:
import pandas as pd
df = pd.DataFrame({"size": ["S", "S", "M", "L"],
"price": [44, 29.99, 10, 19]})
df.groupby('size').agg({'price': 'mean'})

# Assign name to the aggregation
df.groupby('size').agg(
mean_price=('price', 'mean')
)

pandas.DataFrame.combine_first对两个 DataFrame 进行联合操作,实现合并的功能。
combine_first()方法根据 DataFrame 的行索引和列索引,对比两个 DataFrame 中相同位置的数据,优先取非空的数据进行合并。
如果调用combine_first()方法的 df1 中数据非空,则结果保留 df1 中的数据,如果 df1 中的数据为空值且传入combine_first()方法的 df2 中数据非空,则结果取 df2 中的数据,如果 df1 和 df2 中的数据都为空值,则结果保留 df1 中的空值(空值有三种:np.nan、None 和 pd.NaT)。
即使两个 DataFrame 的形状不相同也不受影响,联合时主要是根据索引来定位数据的位置。
import pandas as pd
store1 = pd.DataFrame({
"orange": [None, 5, 9],
"apple": [4, None, 12]
})
store2 = pd.DataFrame({
"orange": [31, 52, 91],
"apple": [11, 71, 21]
})
# Fill null values of the store1 with values at the same
# locations from store2
store1.combine_first(store2)

我们可以根据名称中的子字符串过滤 pandas DataFrame 的列,具体是使用 pandas 的DataFrame.filter功能。
import pandas as pd
df = pd.DataFrame({'Temp': ['Hot', 'Cold', 'Warm', 'Cold'],
'Degree': [35, 3, 15, 2]})
print(df)

df = pd.get_dummies(df, columns=['Temp'])
print(df)

print(df.filter(like='Temp', axis=1))

对于 DataFrame 中的列,我们可以调整其数据类型,使用convert_dtypes()可以快速将它转换为我们需要的数据类型。
import pandas as pd
import numpy as np
df = pd.DataFrame(
{
"a": pd.Series([1, 2, 3], dtype=np.dtype("int32")),
"b": pd.Series(["x", "y", "z"], dtype=np.dtype("O")),
"c": pd.Series([True, False, np.nan], dtype=np.dtype("O")),
"d": pd.Series(["h", "i", np.nan], dtype=np.dtype("O")),
"e": pd.Series([10, np.nan, 20], dtype=np.dtype("float")),
"f": pd.Series([np.nan, 100.5, 200], dtype=np.dtype("float")),
}
)
df.dtypes

new_df = df.convert_dtypes()
new_df.dtypes

在我们处理数据的时候,有时需要根据某个列进行计算得到一个新列,以便后续使用,相当于是根据已知列得到新的列,这个时候assign函数非常方便。
import pandas as pd
time_sentences = ["Saturday: Weekend (Not working day)",
"Sunday: Weekend (Not working day)",
"Monday: Doctor appointment at 2:45pm.",
"Tuesday: Dentist appointment at 11:30 am.",
"Wednesday: basketball game At 7:00pm",
"Thursday: Back home by 11:15 pm.",
"Friday: Take the train at 08:10 am."]
df = pd.DataFrame(time_sentences, columns=['text'])
# Use Assign instead of using direct assignment
# df['text'] = df.text.str.lower()
# df['text_len'] = df.text.str.len()
# df['word_count'] = df.text.str.count(" ") + 1
# df['weekend'] = df.text.str.contains("saturday|sunday", case=False)
print((
df
.assign(text=df.text.str.lower(),
text_len=df.text.str.len(),
word_count=df.text.str.count(" ") + 1,
weekend=df.text.str.contains("saturday|sunday", case=False),
)
))

我们可以使用.read_html()可用于快速合并来自各种网站的表格,我们不用关心它是如何抓取网站HTML的。
import pandas as pd
# 抓取股票资料
table = pd.read_html(
"http://vip.stock.finance.sina.com.cn/q/go.php/vComStockHold/kind/jjzc/index.phtml"
)
table[0].head()

如果我们需要对数据字段进行排序,可以使用.sort_values(),但是它会对所有数据排序,如果我们要获取最大或者最小的 n 个数,可以利用.nlargest()和.nsmallest()。
这里用到的数据集是 ?IMDB电影评分数据集,大家可以通过 ShowMeAI 的百度网盘地址下载。
? 实战数据集下载(百度网盘):公✦众✦号『ShowMeAI研究中心』回复『实战』,或者点击 这里 获取本文 [65]资深数据科学家整理的21个Pandas技巧 『imdbratings数据集』
⭐ ShowMeAI官方GitHub:https://github.com/ShowMeAI-Hub
import pandas as pd
df = pd.read_csv('data/imdbratings.csv',
usecols=['star_rating', 'title', 'genre', 'duration'])
print(df.head())

print(df.nlargest(5, "duration"))

print(df.nsmallest(5, "duration"))

pandas 的DataFrame.rank()函数可以返回字段每个取值的排名。
在以下示例中,创建了一个新的排名列,该列按学生的分数对学生进行排名:
import pandas as pd
df = pd.DataFrame({'Students': ['John', 'Smith', 'Patrick', 'Bob', 'Jose'],
'Marks': [80, 56, 95, 75, 45]})
print(df)

df["Rank"] = df["Marks"].rank(ascending=False)
print(df)

可以为 dataframe 添加颜色样式,增加更多的可读性。Pandas 具有 style 属性,可以设置颜色应用于 DataFrame。
import pandas as pd
df = pd.DataFrame({'Students': ['John', 'Smith', 'Patrick', 'Bob', 'Jose'],
'Physics': [80, 56, 95, 75, 45],
'Mathematics': [90, 85, 55, 65, 75]})
df.set_index('Students', inplace=True)
df

def pass_condition(val):
color = 'blue' if val > 70 else 'red'
return f"background-color: {color}"
df.style.applymap(pass_condition)

关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,
有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳
我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01 客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02 数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit
文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co
嗨~大家好,这里是可莉!今天给大家带来的是7个C语言的经典基础代码~那一起往下看下去把【程序一】打印100到200之间的素数#includeintmain(){ inti; for(i=100;i 【程序二】输出乘法口诀表#includeintmain(){inti;for(i=1;i 【程序三】判断1000年---2000年之间的闰年#includeintmain(){intyear;for(year=1000;year 【程序四】给定两个整形变量的值,将两个值的内容进行交换。这里提供两种方法来进行交换,第一种为创建临时变量来进行交换,第二种是不创建临时变量而直接进行交换。1.创建临时变量来