Pandas 2.2 中文官方教程和指南(三)

绝不原创的飞龙發表於2024-04-24

原文: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,並對每個值返回TrueCountess是名稱的一部分)或FalseCountess不是名稱的一部分)。此輸出可用於使用在資料子集教程中介紹的條件(布林)索引來對資料進行子選擇。由於泰坦尼克號上只有一位女伯爵,我們得到一行作為結果。

注意

字串的更強大的提取操作是支援的,因為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的資料框,並將其拆分為by1by2組:

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的資料框,其中包含ab列的表示式將使用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 來基於 AnimalFeedType 聚合資訊的 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.cutastype("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 的資料框,並將其拆分為 by1by2 組:

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)和列ab的表示式將使用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的資料框,並將其拆分為組by1by2

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,具有列 ab,將使用 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 代表 arraysl 代表 listsd 代表 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的資料框來根據AnimalFeedType聚合資訊的表示式:

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.cutastype("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的資料框根據AnimalFeedType聚合資訊:

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.cutastype("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 中因子的差異的文件。

相關文章