原文:
pandas.pydata.org/docs/
如何操作文字資料
原文:
pandas.pydata.org/docs/getting_started/intro_tutorials/10_text_data.html
-
將所有名稱字元改為小寫。
In [4]: titanic["Name"].str.lower() Out[4]: 0 braund, mr. owen harris 1 cumings, mrs. john bradley (florence briggs th... 2 heikkinen, miss. laina 3 futrelle, mrs. jacques heath (lily may peel) 4 allen, mr. william henry ... 886 montvila, rev. juozas 887 graham, miss. margaret edith 888 johnston, miss. catherine helen "carrie" 889 behr, mr. karl howell 890 dooley, mr. patrick Name: Name, Length: 891, dtype: object
要使
Name
列中的每個字串都變為小寫,選擇Name
列(參見資料選擇教程),新增str
訪問器並應用lower
方法。因此,每個字串都被逐個轉換。
與時間序列教程中具有dt
訪問器的日期時間物件類似,在使用str
訪問器時可以使用許多專門的字串方法。這些方法通常與單個元素的內建字串方法具有匹配的名稱,但是在每個值的列上逐個應用(記得逐元素計算嗎?)。
-
建立一個新列
Surname
,其中包含乘客的姓氏,透過提取逗號前的部分。In [5]: titanic["Name"].str.split(",") Out[5]: 0 [Braund, Mr. Owen Harris] 1 [Cumings, Mrs. John Bradley (Florence Briggs ... 2 [Heikkinen, Miss. Laina] 3 [Futrelle, Mrs. Jacques Heath (Lily May Peel)] 4 [Allen, Mr. William Henry] ... 886 [Montvila, Rev. Juozas] 887 [Graham, Miss. Margaret Edith] 888 [Johnston, Miss. Catherine Helen "Carrie"] 889 [Behr, Mr. Karl Howell] 890 [Dooley, Mr. Patrick] Name: Name, Length: 891, dtype: object
使用
Series.str.split()
方法,每個值都返回一個包含 2 個元素的列表。第一個元素是逗號前的部分,第二個元素是逗號後的部分。In [6]: titanic["Surname"] = titanic["Name"].str.split(",").str.get(0) In [7]: titanic["Surname"] Out[7]: 0 Braund 1 Cumings 2 Heikkinen 3 Futrelle 4 Allen ... 886 Montvila 887 Graham 888 Johnston 889 Behr 890 Dooley Name: Surname, Length: 891, dtype: object
由於我們只對代表姓氏的第一部分感興趣(元素 0),我們可以再次使用
str
訪問器,並應用Series.str.get()
來提取相關部分。事實上,這些字串函式可以連線起來組合多個函式!
到使用者指南
有關提取字串部分的更多資訊,請參閱使用者指南中關於拆分和替換字串的部分。
-
提取關於泰坦尼克號上女伯爵的乘客資料。
In [8]: titanic["Name"].str.contains("Countess") Out[8]: 0 False 1 False 2 False 3 False 4 False ... 886 False 887 False 888 False 889 False 890 False Name: Name, Length: 891, dtype: bool
In [9]: titanic[titanic["Name"].str.contains("Countess")] Out[9]: PassengerId Survived Pclass ... Cabin Embarked Surname 759 760 1 1 ... B77 S Rothes [1 rows x 13 columns]
(對她的故事感興趣嗎?請參閱 維基百科!)
字串方法
Series.str.contains()
檢查列Name
中的每個值是否包含單詞Countess
,並對每個值返回True
(Countess
是名稱的一部分)或False
(Countess
不是名稱的一部分)。此輸出可用於使用在資料子集教程中介紹的條件(布林)索引來對資料進行子選擇。由於泰坦尼克號上只有一位女伯爵,我們得到一行作為結果。
注意
字串的更強大的提取操作是支援的,因為Series.str.contains()
和 Series.str.extract()
方法接受正規表示式,但不在本教程的範圍內。
到使用者指南
更多有關提取字串部分的資訊,請參閱使用者指南中有關字串匹配和提取的部分。
-
泰坦尼克號的乘客中,哪位乘客的名字最長?
In [10]: titanic["Name"].str.len() Out[10]: 0 23 1 51 2 22 3 44 4 24 .. 886 21 887 28 888 40 889 21 890 19 Name: Name, Length: 891, dtype: int64
要獲得最長的名稱,我們首先必須獲取
Name
列中每個名稱的長度。透過使用 pandas 字串方法,對每個名稱單獨應用Series.str.len()
函式(逐元素)。In [11]: titanic["Name"].str.len().idxmax() Out[11]: 307
接下來,我們需要獲取對應位置,最好是表格中名字長度最大的索引標籤。
idxmax()
方法正是這樣做的。它不是字串方法,適用於整數,因此不使用str
。In [12]: titanic.loc[titanic["Name"].str.len().idxmax(), "Name"] Out[12]: 'Penasco y Castellana, Mrs. Victor de Satode (Maria Josefa Perez de Soto y Vallejo)'
基於行的索引名稱(
307
)和列的名稱(Name
),我們可以使用loc
運算子進行選擇,該運算子在子集切片教程中介紹過。 -
在“性別”列中,將“male”的值替換為“M”,將“female”的值替換為“F”。
In [13]: titanic["Sex_short"] = titanic["Sex"].replace({"male": "M", "female": "F"}) In [14]: titanic["Sex_short"] Out[14]: 0 M 1 F 2 F 3 F 4 M .. 886 M 887 F 888 F 889 M 890 M Name: Sex_short, Length: 891, dtype: object
而
replace()
不是一個字串方法,它提供了一種方便的方式來使用對映或詞彙表來轉換某些值。它需要一個dictionary
來定義對映{from : to}
。
警告
還有一個可用的replace()
方法,可以替換特定的字符集。但是,當有多個值的對映時,這將變得:
titanic["Sex_short"] = titanic["Sex"].str.replace("female", "F")
titanic["Sex_short"] = titanic["Sex_short"].str.replace("male", "M")
這將變得繁瑣,並且很容易出錯。想想(或者試試)如果這兩個語句以相反的順序應用會發生什麼…
記住
-
可以使用
str
訪問器使用字串方法。 -
字串方法是逐元素進行的,可以用於條件索引。
-
replace
方法是根據給定字典轉換值的便捷方法。
到使用者指南
使用者指南頁面提供了處理文字資料的全面概述。
與其他工具的比較
原文:
pandas.pydata.org/docs/getting_started/comparison/index.html
-
與 R / R 庫的比較
-
快速參考
-
基本 R
-
plyr
-
reshape / reshape2
-
-
與 SQL 的比較
-
複製 vs. 原地操作
-
選擇
-
WHERE
-
GROUP BY
-
連線
-
UNION
-
限制
-
pandas 對一些 SQL 分析和聚合函式的等效操作
-
更新
-
刪除
-
-
與電子表格的比較
-
資料結構
-
資料輸入/輸出
-
資料操作
-
字串處理
-
合併
-
其他考慮因素
-
-
與 SAS 的比較
-
資料結構
-
資料輸入/輸出
-
資料操作
-
字串處理
-
合併
-
缺失資料
-
GroupBy
-
其他考慮因素
-
-
與 Stata 的比較
-
資料結構
-
資料輸入/輸出
-
資料操作
-
字串處理
-
合併
-
缺失資料
-
GroupBy
-
其他考慮因素
-
與 R/R 庫的比較
譯文:
pandas.pydata.org/docs/getting_started/comparison/comparison_with_r.html
由於 pandas 旨在提供許多人們使用R的資料操作和分析功能,因此本頁面旨在更詳細地檢視R 語言及其許多第三方庫與 pandas 的關係。在與 R 和 CRAN 庫的比較中,我們關心以下幾點:
-
功能性/靈活性:每個工具可以/不可以做什麼
-
效能:操作有多快。最好提供硬性資料/基準
-
易用性:一個工具更容易/更難使用(您可能需要透過並排程式碼比較來判斷)
本頁面還提供了一個為這些 R 包的使用者提供一點翻譯指南的頁面。
快速參考
我們將從一個快速參考指南開始,將一些常見的 R 操作(使用dplyr)與 pandas 的等效操作進行配對。
查詢、過濾、抽樣
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) 但請參見[1] |
distinct(select(df, col1)) |
df[['col1']].drop_duplicates() |
distinct(select(df, col1, col2)) |
df[['col1', 'col2']].drop_duplicates() |
sample_n(df, 10) |
df.sample(n=10) |
sample_frac(df, 0.01) |
df.sample(frac=0.01) |
排序
R | pandas |
---|---|
arrange(df, col1, col2) |
df.sort_values(['col1', 'col2']) |
arrange(df, desc(col1)) |
df.sort_values('col1', ascending=False) |
轉換
R | pandas |
---|---|
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']) |
分組和彙總
R | pandas |
---|---|
summary(df) |
df.describe() |
gdf <- group_by(df, col1) |
gdf = df.groupby('col1') |
summarise(gdf, avg=mean(col1, na.rm=TRUE)) |
df.groupby('col1').agg({'col1': 'mean'}) |
summarise(gdf, total=sum(col1)) |
df.groupby('col1').sum() |
基礎 R
使用 R 的c
進行切片
R 使得透過名稱輕鬆訪問 data.frame
列成為可能
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 中按名稱選擇多列很簡單
In [1]: df = pd.DataFrame(np.random.randn(10, 3), columns=list("abc"))
In [2]: df[["a", "c"]]
Out[2]:
a c
0 0.469112 -1.509059
1 -1.135632 -0.173215
2 0.119209 -0.861849
3 -2.104569 1.071804
4 0.721555 -1.039575
5 0.271860 0.567020
6 0.276232 -0.673690
7 0.113648 0.524988
8 0.404705 -1.715002
9 -1.039268 -1.157892
In [3]: df.loc[:, ["a", "c"]]
Out[3]:
a c
0 0.469112 -1.509059
1 -1.135632 -0.173215
2 0.119209 -0.861849
3 -2.104569 1.071804
4 0.721555 -1.039575
5 0.271860 0.567020
6 0.276232 -0.673690
7 0.113648 0.524988
8 0.404705 -1.715002
9 -1.039268 -1.157892
透過整數位置選擇多個不連續列可以透過iloc
索引器屬性和numpy.r_
的組合實現。
In [4]: named = list("abcdefg")
In [5]: n = 30
In [6]: columns = named + np.arange(len(named), n).tolist()
In [7]: df = pd.DataFrame(np.random.randn(n, n), columns=columns)
In [8]: df.iloc[:, np.r_[:10, 24:30]]
Out[8]:
a b c ... 27 28 29
0 -1.344312 0.844885 1.075770 ... 0.813850 0.132003 -0.827317
1 -0.076467 -1.187678 1.130127 ... 0.149748 -0.732339 0.687738
2 0.176444 0.403310 -0.154951 ... -0.493662 0.600178 0.274230
3 0.132885 -0.023688 2.410179 ... 0.109121 1.126203 -0.977349
4 1.474071 -0.064034 -1.282782 ... -0.858447 0.306996 -0.028665
.. ... ... ... ... ... ... ...
25 1.492125 -0.068190 0.681456 ... 0.428572 0.880609 0.487645
26 0.725238 0.624607 -0.141185 ... 1.008500 1.424017 0.717110
27 1.262419 1.950057 0.301038 ... 1.007824 2.826008 1.458383
28 -1.585746 -0.899734 0.921494 ... 0.577223 -1.088417 0.326687
29 -0.986248 0.169729 -1.158091 ... -2.013086 -1.602549 0.333109
[30 rows x 16 columns]
aggregate
在 R 中,您可能希望將資料拆分為子集併為每個子集計算平均值。使用名為df
的資料框,並將其拆分為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)
groupby()
方法類似於基本的 R aggregate
函式。
In [9]: 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,
...: ],
...: }
...: )
...:
In [10]: g = df.groupby(["by1", "by2"])
In [11]: g[["v1", "v2"]].mean()
Out[11]:
v1 v2
by1 by2
1 95 5.0 55.0
99 5.0 55.0
2 95 7.0 77.0
99 NaN NaN
big damp 3.0 33.0
blue dry 3.0 33.0
red red 4.0 44.0
wet 1.0 11.0
有關更多詳細資訊和示例,請參閱分組文件。
match
/ %in%
在 R 中選擇資料的常見方法是使用%in%
,該運算子使用函式match
定義。運算子%in%
用於返回指示是否存在匹配項的邏輯向量:
s <- 0:4
s %in% c(2,4)
isin()
方法類似於 R 的%in%
運算子:
In [12]: s = pd.Series(np.arange(5), dtype=np.float32)
In [13]: s.isin([2, 4])
Out[13]:
0 False
1 False
2 True
3 False
4 True
dtype: bool
match
函式返回其第一個引數在第二個引數中匹配位置的向量:
s <- 0:4
match(s, c(2,4))
有關更多詳細資訊和示例,請參閱重塑文件。
tapply
tapply
類似於aggregate
,但資料可以是不規則的陣列,因為子類大小可能不規則。使用名為baseball
的資料框,並根據陣列team
檢索資訊:
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()
方法來處理這個問題:
In [14]: import random
In [15]: import string
In [16]: 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),
....: }
....: )
....:
In [17]: baseball.pivot_table(values="batting avg", columns="team", aggfunc="max")
Out[17]:
team team 1 team 2 team 3 team 4 team 5
batting avg 0.352134 0.295327 0.397191 0.394457 0.396194
有關更多詳細資訊和示例,請參閱重塑文件。
subset
query()
方法類似於基本的 R subset
函式。在 R 中,您可能希望獲取data.frame
的行,其中一列的值小於另一列的值:
df <- data.frame(a=rnorm(10), b=rnorm(10))
subset(df, a <= b)
df[df$a <= df$b,] # note the comma
在 pandas 中,有幾種方法可以執行子集。您可以使用query()
或將表示式傳遞為索引/切片,以及標準布林索引:
In [18]: df = pd.DataFrame({"a": np.random.randn(10), "b": np.random.randn(10)})
In [19]: df.query("a <= b")
Out[19]:
a b
1 0.174950 0.552887
2 -0.023167 0.148084
3 -0.495291 -0.300218
4 -0.860736 0.197378
5 -1.134146 1.720780
7 -0.290098 0.083515
8 0.238636 0.946550
In [20]: df[df["a"] <= df["b"]]
Out[20]:
a b
1 0.174950 0.552887
2 -0.023167 0.148084
3 -0.495291 -0.300218
4 -0.860736 0.197378
5 -1.134146 1.720780
7 -0.290098 0.083515
8 0.238636 0.946550
In [21]: df.loc[df["a"] <= df["b"]]
Out[21]:
a b
1 0.174950 0.552887
2 -0.023167 0.148084
3 -0.495291 -0.300218
4 -0.860736 0.197378
5 -1.134146 1.720780
7 -0.290098 0.083515
8 0.238636 0.946550
有關更多詳細資訊和示例,請參閱查詢文件。
with
在 R 中使用名為df
的資料框,其中包含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()
方法的等效表示式將是:
In [22]: df = pd.DataFrame({"a": np.random.randn(10), "b": np.random.randn(10)})
In [23]: df.eval("a + b")
Out[23]:
0 -0.091430
1 -2.483890
2 -0.252728
3 -0.626444
4 -0.261740
5 2.149503
6 -0.332214
7 0.799331
8 -2.377245
9 2.104677
dtype: float64
In [24]: df["a"] + df["b"] # same as the previous expression
Out[24]:
0 -0.091430
1 -2.483890
2 -0.252728
3 -0.626444
4 -0.261740
5 2.149503
6 -0.332214
7 0.799331
8 -2.377245
9 2.104677
dtype: float64
在某些情況下,eval()
比純 Python 中的評估要快得多。更多詳細資訊和示例請參見 eval 文件。
plyr
plyr
是一個用於資料分析的 R 庫,圍繞著 R 中的三種資料結構 a
(陣列)、l
(列表)和 d
(資料框)展開。下表顯示了這些資料結構在 Python 中的對映方式。
R | Python |
---|---|
陣列 | 列表 |
列表 | 字典或物件列表 |
data.frame | 資料框 |
ddply
在 R 中使用名為 df
的 data.frame 來按 month
彙總 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()
方法,將是:
In [25]: 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),
....: }
....: )
....:
In [26]: grouped = df.groupby(["month", "week"])
In [27]: grouped["x"].agg(["mean", "std"])
Out[27]:
mean std
month week
5 1 63.653367 40.601965
2 78.126605 53.342400
3 92.091886 57.630110
6 1 81.747070 54.339218
2 70.971205 54.687287
3 100.968344 54.010081
7 1 61.576332 38.844274
2 61.733510 48.209013
3 71.688795 37.595638
8 1 62.741922 34.618153
2 91.774627 49.790202
3 73.936856 60.773900
更多詳細資訊和示例請參見 分組文件。
reshape / reshape2
meltarray
在 R 中使用名為 a
的 3 維陣列來將其融合成一個 data.frame 的表示式:
a <- array(c(1:23, NA), c(2,3,4))
data.frame(melt(a))
在 Python 中,由於 a
是一個列表,你可以簡單地使用列表推導式。
In [28]: a = np.array(list(range(1, 24)) + [np.NAN]).reshape(2, 3, 4)
In [29]: pd.DataFrame([tuple(list(x) + [val]) for x, val in np.ndenumerate(a)])
Out[29]:
0 1 2 3
0 0 0 0 1.0
1 0 0 1 2.0
2 0 0 2 3.0
3 0 0 3 4.0
4 0 1 0 5.0
.. .. .. .. ...
19 1 1 3 20.0
20 1 2 0 21.0
21 1 2 1 22.0
22 1 2 2 23.0
23 1 2 3 NaN
[24 rows x 4 columns]
meltlist
在 R 中使用名為 a
的列表來將其融合成一個 data.frame 的表示式:
a <- as.list(c(1:4, NA))
data.frame(melt(a))
在 Python 中,這個列表將是一個元組的列表,因此 DataFrame()
方法將其轉換為所需的資料框。
In [30]: a = list(enumerate(list(range(1, 5)) + [np.NAN]))
In [31]: pd.DataFrame(a)
Out[31]:
0 1
0 0 1.0
1 1 2.0
2 2 3.0
3 3 4.0
4 4 NaN
更多詳細資訊和示例請參見 資料結構入門文件。
meltdf
在 R 中使用名為 cheese
的 data.frame 來重新塑造資料框的表示式:
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"))
在 Python 中,melt()
方法是 R 中的等效方法:
In [32]: cheese = pd.DataFrame(
....: {
....: "first": ["John", "Mary"],
....: "last": ["Doe", "Bo"],
....: "height": [5.5, 6.0],
....: "weight": [130, 150],
....: }
....: )
....:
In [33]: pd.melt(cheese, id_vars=["first", "last"])
Out[33]:
first last variable value
0 John Doe height 5.5
1 Mary Bo height 6.0
2 John Doe weight 130.0
3 Mary Bo weight 150.0
In [34]: cheese.set_index(["first", "last"]).stack(future_stack=True) # alternative way
Out[34]:
first last
John Doe height 5.5
weight 130.0
Mary Bo height 6.0
weight 150.0
dtype: float64
更多詳細資訊和示例請參見 重塑文件。
cast
在 R 中,acast
是使用名為 df
的 data.frame 來轉換為更高維陣列的表示式:
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()
:
In [35]: 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,
....: }
....: )
....:
In [36]: mdf = pd.melt(df, id_vars=["month", "week"])
In [37]: pd.pivot_table(
....: mdf,
....: values="value",
....: index=["variable", "week"],
....: columns=["month"],
....: aggfunc="mean",
....: )
....:
Out[37]:
month 5 6 7
variable week
x 1 93.888747 98.762034 55.219673
2 94.391427 38.112932 83.942781
y 1 94.306912 279.454811 227.840449
2 87.392662 193.028166 173.899260
z 1 11.016009 10.079307 16.170549
2 8.476111 17.638509 19.003494
類似於在 R 中使用名為 df
的 data.frame 來基於 Animal
和 FeedType
聚合資訊的 dcast
:
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()
:
In [38]: 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],
....: }
....: )
....:
In [39]: df.pivot_table(values="Amount", index="Animal", columns="FeedType", aggfunc="sum")
Out[39]:
FeedType A B
Animal
Animal1 10.0 5.0
Animal2 2.0 13.0
Animal3 6.0 NaN
第二種方法是使用 groupby()
方法:
In [40]: df.groupby(["Animal", "FeedType"])["Amount"].sum()
Out[40]:
Animal FeedType
Animal1 A 10
B 5
Animal2 A 2
B 13
Animal3 A 6
Name: Amount, dtype: int64
更多詳細資訊和示例請參見 重塑文件 或 分組文件。
factor
pandas 有一種用於分類資料的資料型別。
cut(c(1,2,3,4,5,6), 3)
factor(c(1,2,3,2,2,3))
在 pandas 中可以用 pd.cut
和 astype("category")
實現:
In [41]: pd.cut(pd.Series([1, 2, 3, 4, 5, 6]), 3)
Out[41]:
0 (0.995, 2.667]
1 (0.995, 2.667]
2 (2.667, 4.333]
3 (2.667, 4.333]
4 (4.333, 6.0]
5 (4.333, 6.0]
dtype: category
Categories (3, interval[float64, right]): [(0.995, 2.667] < (2.667, 4.333] < (4.333, 6.0]]
In [42]: pd.Series([1, 2, 3, 2, 2, 3]).astype("category")
Out[42]:
0 1
1 2
2 3
3 2
4 2
5 3
dtype: category
Categories (3, int64): [1, 2, 3]
更多詳情和示例請參閱 分類簡介 和 API 文件。還有關於 與 R 的因子的區別 的文件。
快速參考
我們將從一個快速參考指南開始,將一些常見的 R 操作(使用 dplyr)與 pandas 的等價操作進行對比。
查詢、過濾、抽樣
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) 但見 [1] |
distinct(select(df, col1)) |
df[['col1']].drop_duplicates() |
distinct(select(df, col1, col2)) |
df[['col1', 'col2']].drop_duplicates() |
sample_n(df, 10) |
df.sample(n=10) |
sample_frac(df, 0.01) |
df.sample(frac=0.01) |
排序
R | pandas |
---|---|
arrange(df, col1, col2) |
df.sort_values(['col1', 'col2']) |
arrange(df, desc(col1)) |
df.sort_values('col1', ascending=False) |
轉換
R | pandas |
---|---|
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']) |
分組和彙總
R | pandas |
---|---|
summary(df) |
df.describe() |
gdf <- group_by(df, col1) |
gdf = df.groupby('col1') |
summarise(gdf, avg=mean(col1, na.rm=TRUE)) |
df.groupby('col1').agg({'col1': 'mean'}) |
summarise(gdf, total=sum(col1)) |
df.groupby('col1').sum() |
查詢、過濾、抽樣
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) 但見 [1] |
distinct(select(df, col1)) |
df[['col1']].drop_duplicates() |
distinct(select(df, col1, col2)) |
df[['col1', 'col2']].drop_duplicates() |
sample_n(df, 10) |
df.sample(n=10) |
sample_frac(df, 0.01) |
df.sample(frac=0.01) |
排序
R | pandas |
---|---|
arrange(df, col1, col2) |
df.sort_values(['col1', 'col2']) |
arrange(df, desc(col1)) |
df.sort_values('col1', ascending=False) |
轉換
R | pandas |
---|---|
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']) |
分組和彙總
R | pandas |
---|---|
summary(df) |
df.describe() |
gdf <- group_by(df, col1) |
gdf = df.groupby('col1') |
summarise(gdf, avg=mean(col1, na.rm=TRUE)) |
df.groupby('col1').agg({'col1': 'mean'}) |
summarise(gdf, total=sum(col1)) |
df.groupby('col1').sum() |
基本 R
使用 R 的 c
進行切片
R 使得透過名稱輕鬆訪問 data.frame
列
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 中透過名稱選擇多列很簡單
In [1]: df = pd.DataFrame(np.random.randn(10, 3), columns=list("abc"))
In [2]: df[["a", "c"]]
Out[2]:
a c
0 0.469112 -1.509059
1 -1.135632 -0.173215
2 0.119209 -0.861849
3 -2.104569 1.071804
4 0.721555 -1.039575
5 0.271860 0.567020
6 0.276232 -0.673690
7 0.113648 0.524988
8 0.404705 -1.715002
9 -1.039268 -1.157892
In [3]: df.loc[:, ["a", "c"]]
Out[3]:
a c
0 0.469112 -1.509059
1 -1.135632 -0.173215
2 0.119209 -0.861849
3 -2.104569 1.071804
4 0.721555 -1.039575
5 0.271860 0.567020
6 0.276232 -0.673690
7 0.113648 0.524988
8 0.404705 -1.715002
9 -1.039268 -1.157892
透過整數位置選擇多個不連續的列可以透過 iloc
索引器屬性和 numpy.r_
的組合實現。
In [4]: named = list("abcdefg")
In [5]: n = 30
In [6]: columns = named + np.arange(len(named), n).tolist()
In [7]: df = pd.DataFrame(np.random.randn(n, n), columns=columns)
In [8]: df.iloc[:, np.r_[:10, 24:30]]
Out[8]:
a b c ... 27 28 29
0 -1.344312 0.844885 1.075770 ... 0.813850 0.132003 -0.827317
1 -0.076467 -1.187678 1.130127 ... 0.149748 -0.732339 0.687738
2 0.176444 0.403310 -0.154951 ... -0.493662 0.600178 0.274230
3 0.132885 -0.023688 2.410179 ... 0.109121 1.126203 -0.977349
4 1.474071 -0.064034 -1.282782 ... -0.858447 0.306996 -0.028665
.. ... ... ... ... ... ... ...
25 1.492125 -0.068190 0.681456 ... 0.428572 0.880609 0.487645
26 0.725238 0.624607 -0.141185 ... 1.008500 1.424017 0.717110
27 1.262419 1.950057 0.301038 ... 1.007824 2.826008 1.458383
28 -1.585746 -0.899734 0.921494 ... 0.577223 -1.088417 0.326687
29 -0.986248 0.169729 -1.158091 ... -2.013086 -1.602549 0.333109
[30 rows x 16 columns]
aggregate
在 R 中,您可能希望將資料拆分為子集,併為每個子集計算平均值。使用名為 df
的資料框,並將其拆分為 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)
groupby()
方法類似於基本的 R aggregate
函式。
In [9]: 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,
...: ],
...: }
...: )
...:
In [10]: g = df.groupby(["by1", "by2"])
In [11]: g[["v1", "v2"]].mean()
Out[11]:
v1 v2
by1 by2
1 95 5.0 55.0
99 5.0 55.0
2 95 7.0 77.0
99 NaN NaN
big damp 3.0 33.0
blue dry 3.0 33.0
red red 4.0 44.0
wet 1.0 11.0
有關更多詳細資訊和示例,請參閱分組文件。
match
/ %in%
用 %in%
在 R 中選擇資料的常見方法是使用 match
函式定義的。運算子 %in%
用於返回一個邏輯向量,指示是否有匹配項:
s <- 0:4
s %in% c(2,4)
isin()
方法類似於 R 的 %in%
運算子:
In [12]: s = pd.Series(np.arange(5), dtype=np.float32)
In [13]: s.isin([2, 4])
Out[13]:
0 False
1 False
2 True
3 False
4 True
dtype: bool
match
函式返回其第一個引數在第二個引數中的匹配位置的向量:
s <- 0:4
match(s, c(2,4))
有關更多詳細資訊和示例,請參閱重塑文件。
tapply
tapply
類似於 aggregate
,但資料可以是不規則的,因為子類大小可能不規則。使用名為 baseball
的資料框,並根據陣列 team
檢索資訊:
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()
方法來處理這個問題:
In [14]: import random
In [15]: import string
In [16]: 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),
....: }
....: )
....:
In [17]: baseball.pivot_table(values="batting avg", columns="team", aggfunc="max")
Out[17]:
team team 1 team 2 team 3 team 4 team 5
batting avg 0.352134 0.295327 0.397191 0.394457 0.396194
有關更多詳細資訊和示例,請參閱重塑文件。
subset
query()
方法類似於基本的 R subset
函式。在 R 中,您可能希望獲取data.frame
的行,其中一列的值小於另一列的值:
df <- data.frame(a=rnorm(10), b=rnorm(10))
subset(df, a <= b)
df[df$a <= df$b,] # note the comma
在 pandas 中,有幾種執行子集的方法。您可以使用query()
或將表示式傳遞為索引/切片,以及標準布林索引:
In [18]: df = pd.DataFrame({"a": np.random.randn(10), "b": np.random.randn(10)})
In [19]: df.query("a <= b")
Out[19]:
a b
1 0.174950 0.552887
2 -0.023167 0.148084
3 -0.495291 -0.300218
4 -0.860736 0.197378
5 -1.134146 1.720780
7 -0.290098 0.083515
8 0.238636 0.946550
In [20]: df[df["a"] <= df["b"]]
Out[20]:
a b
1 0.174950 0.552887
2 -0.023167 0.148084
3 -0.495291 -0.300218
4 -0.860736 0.197378
5 -1.134146 1.720780
7 -0.290098 0.083515
8 0.238636 0.946550
In [21]: df.loc[df["a"] <= df["b"]]
Out[21]:
a b
1 0.174950 0.552887
2 -0.023167 0.148084
3 -0.495291 -0.300218
4 -0.860736 0.197378
5 -1.134146 1.720780
7 -0.290098 0.083515
8 0.238636 0.946550
更多詳細資訊和示例請參見查詢文件。
with
在 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()
方法的等價表示式將是:
In [22]: df = pd.DataFrame({"a": np.random.randn(10), "b": np.random.randn(10)})
In [23]: df.eval("a + b")
Out[23]:
0 -0.091430
1 -2.483890
2 -0.252728
3 -0.626444
4 -0.261740
5 2.149503
6 -0.332214
7 0.799331
8 -2.377245
9 2.104677
dtype: float64
In [24]: df["a"] + df["b"] # same as the previous expression
Out[24]:
0 -0.091430
1 -2.483890
2 -0.252728
3 -0.626444
4 -0.261740
5 2.149503
6 -0.332214
7 0.799331
8 -2.377245
9 2.104677
dtype: float64
在某些情況下,eval()
比純 Python 中的評估要快得多。更多詳細資訊和示例請參見評估文件。
使用 R 的c
進行切片
R 可以輕鬆透過名稱訪問data.frame
列
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 中按名稱選擇多個列非常簡單
In [1]: df = pd.DataFrame(np.random.randn(10, 3), columns=list("abc"))
In [2]: df[["a", "c"]]
Out[2]:
a c
0 0.469112 -1.509059
1 -1.135632 -0.173215
2 0.119209 -0.861849
3 -2.104569 1.071804
4 0.721555 -1.039575
5 0.271860 0.567020
6 0.276232 -0.673690
7 0.113648 0.524988
8 0.404705 -1.715002
9 -1.039268 -1.157892
In [3]: df.loc[:, ["a", "c"]]
Out[3]:
a c
0 0.469112 -1.509059
1 -1.135632 -0.173215
2 0.119209 -0.861849
3 -2.104569 1.071804
4 0.721555 -1.039575
5 0.271860 0.567020
6 0.276232 -0.673690
7 0.113648 0.524988
8 0.404705 -1.715002
9 -1.039268 -1.157892
透過iloc
索引器屬性和numpy.r_
的組合可以實現透過整數位置選擇多個非連續列。
In [4]: named = list("abcdefg")
In [5]: n = 30
In [6]: columns = named + np.arange(len(named), n).tolist()
In [7]: df = pd.DataFrame(np.random.randn(n, n), columns=columns)
In [8]: df.iloc[:, np.r_[:10, 24:30]]
Out[8]:
a b c ... 27 28 29
0 -1.344312 0.844885 1.075770 ... 0.813850 0.132003 -0.827317
1 -0.076467 -1.187678 1.130127 ... 0.149748 -0.732339 0.687738
2 0.176444 0.403310 -0.154951 ... -0.493662 0.600178 0.274230
3 0.132885 -0.023688 2.410179 ... 0.109121 1.126203 -0.977349
4 1.474071 -0.064034 -1.282782 ... -0.858447 0.306996 -0.028665
.. ... ... ... ... ... ... ...
25 1.492125 -0.068190 0.681456 ... 0.428572 0.880609 0.487645
26 0.725238 0.624607 -0.141185 ... 1.008500 1.424017 0.717110
27 1.262419 1.950057 0.301038 ... 1.007824 2.826008 1.458383
28 -1.585746 -0.899734 0.921494 ... 0.577223 -1.088417 0.326687
29 -0.986248 0.169729 -1.158091 ... -2.013086 -1.602549 0.333109
[30 rows x 16 columns]
aggregate
在 R 中,您可能希望將資料拆分為子集併為每個子集計算平均值。使用名為df
的資料框,並將其拆分為組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)
groupby()
方法類似於基本的 R aggregate
函式。
In [9]: 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,
...: ],
...: }
...: )
...:
In [10]: g = df.groupby(["by1", "by2"])
In [11]: g[["v1", "v2"]].mean()
Out[11]:
v1 v2
by1 by2
1 95 5.0 55.0
99 5.0 55.0
2 95 7.0 77.0
99 NaN NaN
big damp 3.0 33.0
blue dry 3.0 33.0
red red 4.0 44.0
wet 1.0 11.0
更多詳細資訊和示例請參見分組文件。
match
/ %in%
在 R 中選擇資料的常見方式是使用%in%
,該運算子使用match
函式定義。運算子%in%
用於返回一個邏輯向量,指示是否存在匹配項:
s <- 0:4
s %in% c(2,4)
isin()
方法類似於 R 的%in%
運算子:
In [12]: s = pd.Series(np.arange(5), dtype=np.float32)
In [13]: s.isin([2, 4])
Out[13]:
0 False
1 False
2 True
3 False
4 True
dtype: bool
match
函式返回其第一個引數在第二個引數中匹配位置的向量:
s <- 0:4
match(s, c(2,4))
更多詳細資訊和示例請參見重塑文件。
tapply
tapply
類似於 aggregate
,但資料可以是不規則的陣列,因為子類大小可能不規則。使用名為 baseball
的 data.frame,並根據陣列 team
檢索資訊:
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()
方法來處理這個問題:
In [14]: import random
In [15]: import string
In [16]: 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),
....: }
....: )
....:
In [17]: baseball.pivot_table(values="batting avg", columns="team", aggfunc="max")
Out[17]:
team team 1 team 2 team 3 team 4 team 5
batting avg 0.352134 0.295327 0.397191 0.394457 0.396194
更多詳細資訊和示例請參見重塑文件。
subset
query()
方法類似於基本的 R subset
函式。在 R 中,您可能希望獲取 data.frame
的行,其中一個列的值小於另一個列的值:
df <- data.frame(a=rnorm(10), b=rnorm(10))
subset(df, a <= b)
df[df$a <= df$b,] # note the comma
在 pandas 中,有幾種方法可以執行子集。您可以使用query()
或將表示式傳遞為索引/切片,以及標準布林索引:
In [18]: df = pd.DataFrame({"a": np.random.randn(10), "b": np.random.randn(10)})
In [19]: df.query("a <= b")
Out[19]:
a b
1 0.174950 0.552887
2 -0.023167 0.148084
3 -0.495291 -0.300218
4 -0.860736 0.197378
5 -1.134146 1.720780
7 -0.290098 0.083515
8 0.238636 0.946550
In [20]: df[df["a"] <= df["b"]]
Out[20]:
a b
1 0.174950 0.552887
2 -0.023167 0.148084
3 -0.495291 -0.300218
4 -0.860736 0.197378
5 -1.134146 1.720780
7 -0.290098 0.083515
8 0.238636 0.946550
In [21]: df.loc[df["a"] <= df["b"]]
Out[21]:
a b
1 0.174950 0.552887
2 -0.023167 0.148084
3 -0.495291 -0.300218
4 -0.860736 0.197378
5 -1.134146 1.720780
7 -0.290098 0.083515
8 0.238636 0.946550
更多詳細資訊和示例請參見查詢文件。
with
在 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()
方法,將是:
In [22]: df = pd.DataFrame({"a": np.random.randn(10), "b": np.random.randn(10)})
In [23]: df.eval("a + b")
Out[23]:
0 -0.091430
1 -2.483890
2 -0.252728
3 -0.626444
4 -0.261740
5 2.149503
6 -0.332214
7 0.799331
8 -2.377245
9 2.104677
dtype: float64
In [24]: df["a"] + df["b"] # same as the previous expression
Out[24]:
0 -0.091430
1 -2.483890
2 -0.252728
3 -0.626444
4 -0.261740
5 2.149503
6 -0.332214
7 0.799331
8 -2.377245
9 2.104677
dtype: float64
在某些情況下,eval()
比純 Python 中的評估要快得多。更多詳細資訊和示例請參見 eval 文件。
plyr
plyr
是用於資料分析的分割-應用-組合策略的 R 庫。這些函式圍繞 R 中的三種資料結構展開,a
代表 arrays
,l
代表 lists
,d
代表 data.frame
。下表顯示了這些資料結構在 Python 中的對映方式。
R | Python |
---|---|
array | list |
lists | 字典或物件列表 |
data.frame | dataframe |
ddply
在 R 中使用名為 df
的 data.frame 表示式,您想要按 month
彙總 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()
方法,將是:
In [25]: 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),
....: }
....: )
....:
In [26]: grouped = df.groupby(["month", "week"])
In [27]: grouped["x"].agg(["mean", "std"])
Out[27]:
mean std
month week
5 1 63.653367 40.601965
2 78.126605 53.342400
3 92.091886 57.630110
6 1 81.747070 54.339218
2 70.971205 54.687287
3 100.968344 54.010081
7 1 61.576332 38.844274
2 61.733510 48.209013
3 71.688795 37.595638
8 1 62.741922 34.618153
2 91.774627 49.790202
3 73.936856 60.773900
更多詳細資訊和示例請參見分組文件。
ddply
在 R 中使用名為 df
的 data.frame 表示式,您想要按 month
彙總 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()
方法,將是:
In [25]: 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),
....: }
....: )
....:
In [26]: grouped = df.groupby(["month", "week"])
In [27]: grouped["x"].agg(["mean", "std"])
Out[27]:
mean std
month week
5 1 63.653367 40.601965
2 78.126605 53.342400
3 92.091886 57.630110
6 1 81.747070 54.339218
2 70.971205 54.687287
3 100.968344 54.010081
7 1 61.576332 38.844274
2 61.733510 48.209013
3 71.688795 37.595638
8 1 62.741922 34.618153
2 91.774627 49.790202
3 73.936856 60.773900
更多細節和示例請參見分組文件。
reshape / reshape2
meltarray
在 R 中使用名為a
的三維陣列的表示式,你想要將其融化成資料框:
a <- array(c(1:23, NA), c(2,3,4))
data.frame(melt(a))
在 Python 中,由於a
是一個列表,你可以簡單地使用列表推導式。
In [28]: a = np.array(list(range(1, 24)) + [np.NAN]).reshape(2, 3, 4)
In [29]: pd.DataFrame([tuple(list(x) + [val]) for x, val in np.ndenumerate(a)])
Out[29]:
0 1 2 3
0 0 0 0 1.0
1 0 0 1 2.0
2 0 0 2 3.0
3 0 0 3 4.0
4 0 1 0 5.0
.. .. .. .. ...
19 1 1 3 20.0
20 1 2 0 21.0
21 1 2 1 22.0
22 1 2 2 23.0
23 1 2 3 NaN
[24 rows x 4 columns]
meltlist
在 R 中使用名為a
的列表的表示式,你想要將其融化成資料框:
a <- as.list(c(1:4, NA))
data.frame(melt(a))
在 Python 中,這個列表將是一個元組的列表,所以DataFrame()
方法會將其轉換為所需的資料框。
In [30]: a = list(enumerate(list(range(1, 5)) + [np.NAN]))
In [31]: pd.DataFrame(a)
Out[31]:
0 1
0 0 1.0
1 1 2.0
2 2 3.0
3 3 4.0
4 4 NaN
更多細節和示例請參見資料結構介紹文件。
meltdf
在 R 中使用名為cheese
的資料框的表示式,你想要重塑資料框:
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"))
在 Python 中,melt()
方法是 R 的等價物:
In [32]: cheese = pd.DataFrame(
....: {
....: "first": ["John", "Mary"],
....: "last": ["Doe", "Bo"],
....: "height": [5.5, 6.0],
....: "weight": [130, 150],
....: }
....: )
....:
In [33]: pd.melt(cheese, id_vars=["first", "last"])
Out[33]:
first last variable value
0 John Doe height 5.5
1 Mary Bo height 6.0
2 John Doe weight 130.0
3 Mary Bo weight 150.0
In [34]: cheese.set_index(["first", "last"]).stack(future_stack=True) # alternative way
Out[34]:
first last
John Doe height 5.5
weight 130.0
Mary Bo height 6.0
weight 150.0
dtype: float64
更多細節和示��請參見重塑文件。
轉換
在 R 中,acast
是一個使用名為df
的資料框來轉換為更高維陣列的表示式:
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()
:
In [35]: 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,
....: }
....: )
....:
In [36]: mdf = pd.melt(df, id_vars=["month", "week"])
In [37]: pd.pivot_table(
....: mdf,
....: values="value",
....: index=["variable", "week"],
....: columns=["month"],
....: aggfunc="mean",
....: )
....:
Out[37]:
month 5 6 7
variable week
x 1 93.888747 98.762034 55.219673
2 94.391427 38.112932 83.942781
y 1 94.306912 279.454811 227.840449
2 87.392662 193.028166 173.899260
z 1 11.016009 10.079307 16.170549
2 8.476111 17.638509 19.003494
類似於dcast
,它使用在 R 中名為df
的資料框來根據Animal
和FeedType
聚合資訊的表示式:
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()
:
In [38]: 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],
....: }
....: )
....:
In [39]: df.pivot_table(values="Amount", index="Animal", columns="FeedType", aggfunc="sum")
Out[39]:
FeedType A B
Animal
Animal1 10.0 5.0
Animal2 2.0 13.0
Animal3 6.0 NaN
第二種方法是使用groupby()
方法:
In [40]: df.groupby(["Animal", "FeedType"])["Amount"].sum()
Out[40]:
Animal FeedType
Animal1 A 10
B 5
Animal2 A 2
B 13
Animal3 A 6
Name: Amount, dtype: int64
更多細節和示例請參見重塑文件或分組文件。
factor
pandas 有一個用於分類資料的資料型別。
cut(c(1,2,3,4,5,6), 3)
factor(c(1,2,3,2,2,3))
在 pandas 中,可以透過pd.cut
和astype("category")
來實現:
In [41]: pd.cut(pd.Series([1, 2, 3, 4, 5, 6]), 3)
Out[41]:
0 (0.995, 2.667]
1 (0.995, 2.667]
2 (2.667, 4.333]
3 (2.667, 4.333]
4 (4.333, 6.0]
5 (4.333, 6.0]
dtype: category
Categories (3, interval[float64, right]): [(0.995, 2.667] < (2.667, 4.333] < (4.333, 6.0]]
In [42]: pd.Series([1, 2, 3, 2, 2, 3]).astype("category")
Out[42]:
0 1
1 2
2 3
3 2
4 2
5 3
dtype: category
Categories (3, int64): [1, 2, 3]
更多細節和示例請參見分類介紹和 API 文件。還有關於 R 的因子的差異的文件。
meltarray
在 R 中使用名為a
的三維陣列的表示式,你想要將其融化成資料框:
a <- array(c(1:23, NA), c(2,3,4))
data.frame(melt(a))
在 Python 中,由於a
是一個列表,你可以簡單地使用列表推導式。
In [28]: a = np.array(list(range(1, 24)) + [np.NAN]).reshape(2, 3, 4)
In [29]: pd.DataFrame([tuple(list(x) + [val]) for x, val in np.ndenumerate(a)])
Out[29]:
0 1 2 3
0 0 0 0 1.0
1 0 0 1 2.0
2 0 0 2 3.0
3 0 0 3 4.0
4 0 1 0 5.0
.. .. .. .. ...
19 1 1 3 20.0
20 1 2 0 21.0
21 1 2 1 22.0
22 1 2 2 23.0
23 1 2 3 NaN
[24 rows x 4 columns]
meltlist
在 R 中使用名為a
的列表的表示式,你想要將其融化成資料框:
a <- as.list(c(1:4, NA))
data.frame(melt(a))
在 Python 中,這個列表將是一個元組的列表,所以DataFrame()
方法會將其轉換為所需的資料框。
In [30]: a = list(enumerate(list(range(1, 5)) + [np.NAN]))
In [31]: pd.DataFrame(a)
Out[31]:
0 1
0 0 1.0
1 1 2.0
2 2 3.0
3 3 4.0
4 4 NaN
更多詳細資訊和示例請參見資料結構介紹文件。
meltdf
在 R 中使用名為cheese
的資料框進行資料重塑的表示式:
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"))
在 Python 中,melt()
方法相當於 R 中的:
In [32]: cheese = pd.DataFrame(
....: {
....: "first": ["John", "Mary"],
....: "last": ["Doe", "Bo"],
....: "height": [5.5, 6.0],
....: "weight": [130, 150],
....: }
....: )
....:
In [33]: pd.melt(cheese, id_vars=["first", "last"])
Out[33]:
first last variable value
0 John Doe height 5.5
1 Mary Bo height 6.0
2 John Doe weight 130.0
3 Mary Bo weight 150.0
In [34]: cheese.set_index(["first", "last"]).stack(future_stack=True) # alternative way
Out[34]:
first last
John Doe height 5.5
weight 130.0
Mary Bo height 6.0
weight 150.0
dtype: float64
更多詳細資訊和示例請參見重塑文件。
cast
在 R 中,acast
是使用名為df
的資料框進行高維陣列轉換的表示式:
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()
:
In [35]: 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,
....: }
....: )
....:
In [36]: mdf = pd.melt(df, id_vars=["month", "week"])
In [37]: pd.pivot_table(
....: mdf,
....: values="value",
....: index=["variable", "week"],
....: columns=["month"],
....: aggfunc="mean",
....: )
....:
Out[37]:
month 5 6 7
variable week
x 1 93.888747 98.762034 55.219673
2 94.391427 38.112932 83.942781
y 1 94.306912 279.454811 227.840449
2 87.392662 193.028166 173.899260
z 1 11.016009 10.079307 16.170549
2 8.476111 17.638509 19.003494
類似於dcast
,它使用 R 中名為df
的資料框根據Animal
和FeedType
聚合資訊:
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()
:
In [38]: 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],
....: }
....: )
....:
In [39]: df.pivot_table(values="Amount", index="Animal", columns="FeedType", aggfunc="sum")
Out[39]:
FeedType A B
Animal
Animal1 10.0 5.0
Animal2 2.0 13.0
Animal3 6.0 NaN
第二種方法是使用groupby()
方法:
In [40]: df.groupby(["Animal", "FeedType"])["Amount"].sum()
Out[40]:
Animal FeedType
Animal1 A 10
B 5
Animal2 A 2
B 13
Animal3 A 6
Name: Amount, dtype: int64
更多詳細資訊和示例請參見重塑文件或分組文件。
factor
pandas 有一種用於分類資料的資料型別。
cut(c(1,2,3,4,5,6), 3)
factor(c(1,2,3,2,2,3))
在 pandas 中,可以透過pd.cut
和astype("category")
來實現:
In [41]: pd.cut(pd.Series([1, 2, 3, 4, 5, 6]), 3)
Out[41]:
0 (0.995, 2.667]
1 (0.995, 2.667]
2 (2.667, 4.333]
3 (2.667, 4.333]
4 (4.333, 6.0]
5 (4.333, 6.0]
dtype: category
Categories (3, interval[float64, right]): [(0.995, 2.667] < (2.667, 4.333] < (4.333, 6.0]]
In [42]: pd.Series([1, 2, 3, 2, 2, 3]).astype("category")
Out[42]:
0 1
1 2
2 3
3 2
4 2
5 3
dtype: category
Categories (3, int64): [1, 2, 3]
更多詳細資訊和示例請參見分類介紹和 API 文件。還有一份關於 R 中因子的差異的文件。