R语言与pandas的爱恨情仇(注:摘抄)
具体内容可以上pandas下载PDF文档进行学习,本人在这里仅仅是摘抄它的内容。用于学习,无商业用途。请支持原创。(文档62页起)
一:一些函数的用法比较。
Querying,filtering,sampling,sorting,transforming,grouping,summarizing
| R | pandas |
|---|---|
dim(df) |
df.shape |
head(df) |
df.head() |
slice(df,1:10) |
df.iloc[:9] |
filter(df,col1==1,col2==1) |
df.query('col1==1&col2==1') |
df[df$col1==1&df$col2==1,] |
df[(df.col1==1)&(df.col2==1)] |
select(df,col1,col2) |
df[['col1','col2']] |
select(df,col1:col3) |
df.loc[:,'col1':'col3'] |
select(df,-(col1:col3)) |
df.drop(cols_to_drop,axis=1) |
distanct(select(df,col1)) |
df[['col1']].drop_duplicates() |
distance(select(df,col1,col2)) |
df[['col1','col2']].drop_duplicates() |
sample_n(df,10) |
df.sample(n=10) |
sample_frac(df,0.01) |
df.sample(frc=0.01) |
arrange(df,col1,col2) |
df.sort_values(['col1','col2']) |
arrange(df,desc(col1)) |
df.sort_values('col1',ascending=False) |
select(df,col_one=col1) |
df.rename(columns={'col1':'col_one'})['col_one'] |
rename(df,col_one=col1) |
df.rename(columns={'col1':'col_one'}) |
mutate(df,c=a-b) |
df.assign(c=df['a']-df['b']) |
summary(df) |
df.describe() |
gdf<-group_by(df,col1) |
gdf = df.groupby('col1') |
summarise(gdf,avg=mean(col,na.rm=TRUE)) |
df.groupby('col1').agg({'col1':'mean'}) |
summarise(gdf) |
df.groupby('col1').sum() |
二:基本的R
R语言的一些语句是这样的:
df <- data.frame(a=rnorm(5), b=rnorm(5), c=rnorm(5), d=rnorm(5), e=rnorm(5))
df[, c("a", "c", "e")]
#或者
df <- data.frame(matrix(rnorm(1000), ncol=100))
df[, c(1:10, 25:30, 40, 50:100)]
而pandas的表达是这样的:
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(10, 3), columns=list("abc"))
df[["a","b"]]
df.loc[:,["a","c"]]
通过整数位置选择多个非连续列可以通过iloc索引属性 和 numpy.r _ 的组合来实现。
named = list("abcdefg")
n = 30
columns = named + np.arange(len(named),n).tolist()
df = pd.DataFrame(np.random.randn(n,n),columns = columns)
df.head()
df.iloc[:, np.r_[:10, 24:30]]
np.r_的使用方法要注意一下子。
在 R 中,你可能想把数据分割成子集,并计算每个子集的平均值。使用一个名为 df 的data.frame并将它分成 by1和 by2组,代码如下:
df <- data.frame(
v1 = c(1,3,5,7,8,3,5,NA,4,5,7,9),
v2 = c(11,33,55,77,88,33,55,NA,44,55,77,99),
by1 = c("red", "blue", 1, 2, NA, "big", 1, 2, "red", 1, NA, 12),
by2 = c("wet", "dry", 99, 95, NA, "damp", 95, 99, "red", 99, NA, NA))
aggregate(x=df[, c("v1", "v2")], by=list(mydf2$by1, mydf2$by2), FUN = mean)
在pandas中我们可以使用groupby()函数来类似与R中的aggregate函数。
df = pd.DataFrame(
{
"v1":[1,3,5,7,8,3,5,np.nan,4,5,7,9],
"v2":[11,33,55,77,88,33,55,np.nan,44,55,77,99],
"by1":["red","blue",1,2,np.nan,"big",1,2,"red",1,np.nan,12],
"by2":["wet","dry",99,95,np.nan,"damp",95,99,"red",99,np.nan,np.nan],
}
)
g = df.groupby(["by1","by2"])
g[["v1","v2"]].mean()
在 R 中选择数据的一种常见方法是使用%in% ,这是使用函数匹配定义的。%in% 中的运算符 用于返回一个逻辑向量,指示是否有匹配项:例如:
s <- 0:4
s %in% c(2,4)
match(s,c(2,4))
pandas中使用isin()来代替%in%,式例如下:
s = pd.Series(np.arange(5),dtype=np.float32)
s.isin([2,4])
Match 函数返回第二个参数中第一个参数的匹配位置向量
tapply 类似于aggregate,但数据可能是不规则的数组,因为子类大小可能是不规则的。使用一个叫棒球的数据框架,根据数组小组检索信息。
baseball <- data.frame(team=gl(5,5,
labels = paste("Team",LETTERS[1:5])),
player = sample(letters,25),
batting.average = runif(25,.200,.400))
tapply(baseball$batting.average,baseball.example$team,max)
在pandas中,我们可能使用pivot_table()方法来处理它:
import random
import string
baseball = pd.DataFrame(
{
"team":["team %d" %(x+1) for x in range(5)] * 5,
"player": random.sample(list(string.ascii_lowercase),25),
"batting avg":np.random.uniform(0.200,0.400,25),
}
)
baseball.pivot_table(values="batting avg",columns = "team", aggfunc = np.max)
更多的一些信息:
import datetime
df = pd.DataFrame(
{
"A":["one","one","two","three"] * 6,
"B":["A","B","C"]*8,
"C":["foo","foo","foo","bar","bar","bar"] * 4,
"D":np.random.randn(24),
"E":np.random.randn(24),
"F":[datetime.datetime(2013,i,1) for i in range(1,13)]+
[datetime.datetime(2013,i,15) for i in range(1, 13)],
}
)
pd.pivot_table(df,values = "D", index = ["A","B"],columns = ["C"])
pd.pivot_table(df,index=["A","B"], columns = ["C"])
query ()方法类似于基 R 子集函数。在 R 中,你可能想要得到一个 data.frameas 的行,其中一列的值小于另一列的值,R的表达方式为:
df <- data.frame(a=rnoorm(10),b=rnorm(10))
subset(df,a<= b)
df[df$a <= df$b,]
在pandas中有几种方法可以执行子设置,你能够使用query()或者传递一个表达式,就好像它是一个索引/片段以及标准的布尔索引,其代码表达式为:
df = pd.DataFrame({"a":np.random.randn(10),"b":np.random.randn(10)})
df.query("a<=b")
df[df["a"] <= df["b"]]
df.loc[df["a"] <= df["b"]]
在 r 中使用一个名为 df 的 data.frame 表达式,其中包含列 a 和列 b,可以使用with这样的函数来求值:
df <- data.frame(a=rnorm(10), b=rnorm(10))
with(df, a + b)
df$a + df$b # same as the previous expression
在pandas中设备的表达式,使用eval()函数的方法,代码表达式为:
df = pd.DataFrame({"a":np.random.randn(10),"b":np.random.randn(10)})
df.eval("a+b")
在某些情况下 eval ()会比纯 python 中的计算快得多。更多细节和例子请参见 eval 文档。
plyr 是一个用于数据分析的split-apply-combine策略的 R库。函数围绕 R 中的三个数据结构运行,a 用于数组,l 用于列表,d 用于 data.frame。下面的表格显示了这些数据结构是如何用 python 映射的:
| R | python |
|---|---|
array |
list |
lists |
dictionary or list of objects |
data.frame |
dataframe |
在 R中使用一个名为 df 的 data.frame 表达式,在这里你需要按月汇总 x:
require(plyr)
df <- data.frame(
x = runif(120, 1, 168),
y = runif(120, 7, 334),
z = runif(120, 1.7, 20.7),
month = rep(c(5,6,7,8),30),
week = sample(1:4, 120, TRUE)
)
ddply(df, .(month, week), summarize,
mean = round(mean(x), 2),
sd = round(sd(x), 2))
在pandas里,使用groupby()的方法,如下:
df = pd.DataFrame(
{
"x":np.random.uniform(1.0,168.0,120),
"y":np.random.uniform(7.0,334.0,120),
"z":np.random.uniform(1.7,20.7,120),
"month":[5,6,7,8] * 30,
"week":np.random.randint(1,4,120),
}
)
grouped = df.groupby(["month","week"])
grouped["x"].agg([np.mean,np.std])
在R使用一个三维数组的表达式把它融合成一个 data.frame.
a <- array(c(1:23,NA),c(2,3,4))
data.frame(melt(a))
在python中,因为a是一个表格,所以我们可以使用表格的表达式。
a = np.array(list(range(1,24))+[np.NAN]).reshape(2,3,4)
pd.DataFrame([tuple(list(x)+[val]) for x, val in np.ndenumerate(a)])
在R中融合表格方法:
a <- as.list(c(1:4,NA))
data.frame(melt(a))
pandas中的方法为:
a = list(enumerate(list(range(1,5))+ [np.NAN]))
pd.DataFrame(a)
在R中方法:
cheese <- data.frame(
first = c('John', 'Mary'),
last = c('Doe', 'Bo'),
height = c(5.5, 6.0),
weight = c(130, 150)
)
melt(cheese, id=c("first", "last"))
pandas中的方法为:
cheese = pd.DataFrame(
{
"first":["John","Mary"],
"last":["Doe","Bo"],
"height":[5.5,6.0],
"weight":[130,150],
}
)
pd.melt(cheese,id_vars=["first","last"])
在R中方法:
cheese <- data.frame(
first = c('John', 'Mary'),
last = c('Doe', 'Bo'),
height = c(5.5, 6.0),
weight = c(130, 150)
)
melt(cheese, id=c("first", "last"))
pandas中的方法为:
cheese = pd.DataFrame(
{
"first":["John","Mary"],
"last":["Doe","Bo"],
"height":[5.5,6.0],
"weight":[130,150],
}
)
pd.melt(cheese,id_vars=["first","last"])
cheese.set_index(["first","last"]).stack()
在R中方法(cast):
df <- data.frame(
x = runif(12, 1, 168),
y = runif(12, 7, 334),
z = runif(12, 1.7, 20.7),
month = rep(c(5,6,7),4),
week = rep(c(1,2), 6)
)
mdf <- melt(df, id=c("month", "week"))
acast(mdf, week ~ month ~ variable, mean)
在python中最好的方式是利用pivot_table():
df = pd.DataFrame(
{
"x":np.random.uniform(1.0,168.0,12),
"y":np.random.uniform(7.0,334.0,12),
"z":np.random.uniform(1.7,20.7,12),
"month":[5,6,7] * 4,
"week":[1,2] * 6,
}
)
mdf = pd.melt(df,id_vars=["month","week"])
pd.pivot_table(
mdf,
values = "value",
index = ["variable","week"],
columns = ["month"],
aggfunc = np.mean,
)
在R中方法:
df <- data.frame(
Animal = c('Animal1', 'Animal2', 'Animal3', 'Animal2', 'Animal1',
'Animal2', 'Animal3'),
FeedType = c('A', 'B', 'A', 'A', 'B', 'B', 'A'),
Amount = c(10, 7, 4, 2, 5, 6, 2)
)
dcast(df, Animal ~ FeedType, sum, fill=NaN)
# Alternative method using base R
with(df, tapply(Amount, list(Animal, FeedType), sum))
在python中最好的方式是利用pivot_table().
df = pd.DataFrame(
{
"Animal":['Animal1', 'Animal2', 'Animal3', 'Animal2', 'Animal1',
'Animal2', 'Animal3'],
"FeedType":['A', 'B', 'A', 'A', 'B', 'B', 'A'],
"Amount":[10, 7, 4, 2, 5, 6, 2],
}
)
df.pivot_table(values="Amount", index="Animal", columns="FeedType", aggfunc="sum")
方法二:
df.groupby(["Animal", "FeedType"])["Amount"].sum()
pandas有分类数据的数据类型,例如,在R中是这样的:
cut(c(1,2,3,4,5,6), 3)
factor(c(1,2,3,2,2,3))
而在pandas中是这样的:
pd.cut(pd.Series([1, 2, 3, 4, 5, 6]), 3)
pd.Series([1, 2, 3, 2, 2, 3]).astype("category")