Hyper-Positive-Diary

TWICE/遊戯王/バイオインフォ/読書記録/アニメの感想等を走り書きします。

【Python】Rユーザーに優しいPandasの使い方

f:id:slmnphmet1-2:20200316145952j:plain

元々僕はRユーザーでしたが、修士生活を通してPythonを書かなければならない機会が増え、 今では主に、研究でもPythonを使っています。

当初、「Rでできたこの処理、Pythonでどうやるんだっけ?」 ということが度々起こり、調べては忘れ、調べては忘れを繰り返していました。 本来解析やコーディングに時間を割きたい身からしたら、 この時間はすごくタイムロスですよね。

特に当初戸惑ったのが、Rのdata.frameとPythonのPandas.DataFrameの違いです。 要素へのアクセスや結合の仕方が、Rと同じような書き方だとうまくいかず、 イライラした経験、皆さんもあるのではないでしょうか。

この記事は、僕のようなRユーザーがPandasを使ったときに、 あちこちの記事を調べなくてもスムースにコーディングを行えるように書きました。

もし皆さんにとって少しでも役に立ちそうであれば、 ご一読ください。

R-Python対応表

RとPythonで対応している部分については、こちらにまとめてあります。 ほとんどの処理はこれで事足りると思われます。

操作 R Python
csvから読み込み read.csv(path) pd.read_csv(path)
csvから読み込み(index列の指定) read.csv(path, row.names=1) pd.read_csv(path, index_col=0)
csvから読み込み(区切り文字の指定) read.csv(path, sep="\t") pd.read_csv(path, sep="\t")
上からn行 head(df, n) df.head(n)
下からn行 tail(df, n) df.tail(n)
共分散 cov(df) df.cov()
転置 t(df) df.T
行ごとの和 apply(df, 1, sum) df.sum(axis=1)
列ごとの和 apply(df, 2, sum) df.sum(axis=0)
行ごとの標準偏差 apply(df, 1, sd) df.std(axis=1)
列ごとの標準偏差 apply(df, 2, sd) df.std(axis=0)
自作関数の適用(行ごと) apply(df, 1, function(x) { ...}) df.apply(lambda x: ..., axis=1)
自作関数の適用(列ごと) apply(df, 2, function(x) { ...}) df.apply(lambda x: ..., axis=2)
列Aの値の出現回数を集計 table(df[, "A"]) df["A"].value_counts()
列Aの値を昇順で並べ替え sort(df[,"A"]) df["A"].sort_values()
列Aの値を降順で並べ替え sort(df[, "A"], decreasing=TRUE) df["A"].sort_values(ascending=False)
列Aの値でDataFrame全体を並べ替え df[order(df[,"A"]),] df.sort_values("A")
行名へのアクセス rownames(df) df.index
列名へのアクセス colnames(df) df.columns
i行目、j列目の要素へのアクセス df[i, j] df.iloc[i, j]
i1~i2行、j1~j2列へのアクセス df[i1:i2, j1:j2] df.iloc[i1:i2, j1:j2]
全行、j1~j2列へのアクセス df[, j1:j2] df.iloc[:, j1:j2]
i1~i2行、全列へのアクセス df[i1:i2, ] df.iloc[i1:i2, :]
行名a, 列名bの要素へのアクセス df["a", "b"] df.loc["a", "b"]
横方向の結合 cbind(df1, dfd2) pd.concat([df1, df2], axis=1)
縦方向の結合 rbind(df1, dfd2) pd.concat([df1, df2], axis=0)

準備

以下では、上記の表で説明が不十分だったり、RにはないPandasの便利機能だったりについて述べていきたいと思います。

今回はRのirisデータをcsvとして吐き出し、 pythonのDataFrameとして読み込み、 Pandasの解説をしていきます。

pathには自分の好きな場所を指定して下さい。

data(iris)
path <- "~/pandas_example.csv"
write.csv(iris, path)
df <- read.csv(path, row.names=1)
import pandas as pd
path = "~/pandas_example.csv"
df = pd.read_csv(path, index_col=0)
df.head()

jupyter上などで、2つカーネルを立ち上げ、ポチポチ実行しつつ 対比するとわかりやすいかもしれません。

Pythonオブジェクト指向

オブジェクト指向くらい分かっとるわ!!ボケ!!という人にとっては時間の無駄なので、躊躇なく飛ばして下さい。

オブジェクト指向とは

そもそもPandasとRのdata.frameの一番の違いは、 pythonオブジェクト指向であるという点です。 オブジェクト指向では、オブジェクト(変数だったりモジュールだったり)がattributeという変数のようなものと、 methodという関数のようなものを内部に持っています。 オブジェクト指向のメリットについては、別の記事で紹介しておりますので、そちらも参照ください。

(1. blog.hatena.ne.jp)

(2. blog.hatena.ne.jp )

Pythonにおけるattribute/methodへのアクセス

attributeにアクセスするには、 object_name.attribute_name というふうに指定します。

例えば、aという名前のlist型のオブジェクトが持っている、 __class__というattributeにアクセスしたいときは、

a = [1, 2, 3]
print(a.__class__)

と書きます。これにより、 aのクラスが何かを確認できます(もちろんlist型です)。

methodを用いたい時も同様です。 object_name.method_name() とします。()の中には、そのmethodの引数を入れます。

例えば、配列a内の「1」という数字を除去したいときは、

a.remove(1)
print(a)

とします。

オブジェクトaにどのようなattribute/methodが定義されているかは、 以下のようにして確認することができます。

dir(a)
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__delitem__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__getitem__',
 '__gt__',
 '__hash__',
 '__iadd__',
 '__imul__',
 '__init__',
 '__init_subclass__',
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 '__mul__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__reversed__',
 '__rmul__',
 '__setattr__',
 '__setitem__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 'append',
 'clear',
 'copy',
 'count',
 'extend',
 'index',
 'insert',
 'pop',
 'remove',
 'reverse',
 'sort']

配列1つとっても、たくさんのattribute/methodがありますね。

以降、このようなオブジェクト指向の仕組みが分かっているとして、 PandasのオブジェクトであるDataFrameとSeriesについて、話を進めます。

DataFrameとSeries

Rのdata.frameに慣れている人は、Pandasを使い始めた時、 Seriesの扱いについて戸惑うと思います。 ※ Seriesくらいわかっとるわボケ!!という人にとっては時間の無駄なので、躊躇なく飛ばして下さい。

DataFrameは、Rのdata.frameと同様に、 テーブルデータを扱うための型であり、 data.frameに慣れていれば直感でDataFrameをいじることができます。 しかしSeriesに関しては、厳密にはR内に対応するものがはありません。

ただし、「PandasのSeries \fallingdotseq name付きのVector」と思っておくと、イメージが湧きやすいかもしれません。

Seriesについて、押さえておきたい特徴としては、 「DataFrameの1列」であることが挙げられます。

species = df["Species"]
species.__class__

この出力は、pandas.core.series.Seriesとなるはずです。 これは、DataFrameから1列を抜き出した時、それがSeriesとして扱われることを意味します。

以上のようなことがわかれば、Seriesについての直感的な理解はつかめたと思います。

ところで、Seriesが、Rにおける「name付きのVector」と大きく異なる点は、 SeriesがNameというattributeを持っている点です。

print(species)
1         setosa
2         setosa
3         setosa
4         setosa
5         setosa
         ...    
146    virginica
147    virginica
148    virginica
149    virginica
150    virginica
Name: Species, Length: 150, dtype: object

Name: Speciesとありますが、 これは、元のDataFrameのcolumnに、 Speciesという名前で保存されていることを意味します。

逆に、Seriesオブジェクトを既存のDataFrameにくっつける時、 column名は、SeriesのNameとなります。RのVectorと同じ感覚でSeriesを使っていると、 この点でつまづくことがある(僕だけかもしれません)かと思うので、 是非覚えておきたい点です。

代表的なmethod

PandasのDataFrameは、オブジェクト指向で書かれているため、 様々なmethodが内蔵されています。

既存の組込関数をDataFrameに適用するだけでも十分な時もありますが、 methodを適用することが便利な時もあります。ですので、下で取り上げたようなものについては、 是非使いこなしたいところです。

head, tail

Rのhead関数、tail関数に対応するmethodが、 DataFrameには備わっています。

df.head()
df.tail()

defaultでは5行を表示してくれますが、 出力する行数を増やしたいときは、

df.head(10)

のように、表示したい行数を引数として指定してみて下さい。

sum, mean, std

sum/mean/stdは、それぞれ、合計/平均/標準偏差を求めるためのmethodです。 これをDataFrameに適用すると次のようになります。

df.sum()
Sepal.Length                                                876.5
Sepal.Width                                                 458.6
Petal.Length                                                563.7
Petal.Width                                                 179.9
Species         setosasetosasetosasetosasetosasetosasetosaseto...
dtype: object

default(axis=0)では、各列についての和がSeriesの形で出力されます。 Rと異なり、pythonではstr型の足し算が定義されているため、 Speciesについての和は、全文字をつなげたものになります。

各行についての和を求めたいときは、

df.sum(axis=1)

とします。

1      10.2
2       9.5
3       9.4
4       9.4
5      10.2
       ... 
146    17.2
147    15.7
148    16.7
149    17.3
150    15.8
Length: 150, dtype: float64

Rの書き方では、前者が

apply(df, 2, sum)

に、後者が

apply(df, 1, sum)

に対応すると思っておいていいでしょう。

また、Seriesについても、sumを適用することができます。

df["Petal.Length"].sum()

この場合は、Seriesの全要素についての和が返ってきます。

ところで、Rで、

sum(df[,c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width")])

を行うと、data.frame内の全要素の和を返します。 これに直接対応するpandasのmethodはないので、

df[["Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width"]].sum().sum()

と2回sumを行いましょう。

以上のような処理は、mean/stdについても同様に扱うことができます。

cov

covはDataFrameのみに定義されるmethodです。各列の分散共分散行列が返り値となります。

df.cov()
 Sepal.Length    Sepal.Width Petal.Length    Petal.Width
Sepal.Length    0.685694    -0.042434   1.274315    0.516271
Sepal.Width -0.042434   0.189979    -0.329656   -0.121639
Petal.Length    1.274315    -0.329656   3.116278    1.295609
Petal.Width 0.516271    -0.121639   1.295609    0.581006

Speciesについては他のcolumnと共分散が定義できないので、 自動で無視されます。

対応するRの関数は、

cov(df[,c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width")])

もしくは

var(df[,c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width")])

です。やはり、Pandasの場合は、str型が入ったcolumnを除去しなくていい点が便利ですね。

T

DataFrameを転置したいときは、

df.T

としましょう。

厳密にはTは、methodではなく、attributeになります(DataFrameオブジェクトを定義する際、転置したものも同時に保存されるんですね)。

value_counts

Speciesというcolumnには、iris(あやめ)の品種が記されています。 これらの登場回数を知りたいとします。

そんな時便利なのが、value_countsです。 value_countsは、Seriesオブジェクトに定義されますので、

df["Species"].value_counts()

としてみましょう。aとbの内訳が、

setosa        50
virginica     50
versicolor    50
Name: Species, dtype: int64

のように出力されるはずです。

これは、Rの

table(df[,"Species"])

に対応します。

sort_values

Seriesの場合

df["Petal.Length"]の値を、昇順、もしくは降順に並べ替えたいとします。

昇順であれば、

df["Petal.Length"].sort_values()

降順であれば、

df["Petal.Length"].sort_values(ascending=False)

としましょう。 これは、Rのsort関数と等価です。

sort(df[, "Petal.Length"])

DataFrameの場合

DataFrameにもsort_valuesは備わっていますが、少々使い勝手が違います。

df.sort_values("Petal.Length")

これにより、Aが昇順になるように、DataFrameの行全体が入れ替わります。 これは、order関数を使った以下のRコードと等価です。

df[order(df[,"Petal.Length"]),]

apply

Pandasのapplyは、Rのそれとほぼ同じように扱うことができます。 例えば、applyで関数sumを適用するには、以下のように書きます。

df[["Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width"]].apply(sum,axis=0)
df[["Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width"]].apply(sum,axis=1)

上記の処理では、DataFrameのsum methodと同じ出力を得ることができます。 しかし、applyで適用しているのは、python内のdefaultのsum関数です。これは、str型には適用できないため、Speciesのcolumnを除去する必要があります。

これだけでは、applyのありがたみの実感が薄いかと思うので、 lambdaで自作関数を適用する例を見てみましょう。

df.apply(lambda x : x["Sepal.Length"]* x["Pepal.Length"], axis=1)

この処理では、各行ごとに、Sepal.LengthとPetal.Lengthをかけた値を返してくれます。lambda x: のあとには、自分の好きな処理を書いて良いのですが、慣れてくれば自由度の高い処理を投げることができるでしょう。

Rでは以下のコードと等価ですね。

apply(df, 1, function(x) {x["Setal.Length"]*x["Petal.Length"]})

groupby

df.groupby("Species").mean()
Sepal.Length    Sepal.Width Petal.Length    Petal.Width
Species             
setosa  5.006   3.428   1.462   0.246
versicolor  5.936   2.770   4.260   1.326
virginica   6.588   2.974   5.552   2.026

groupbyは、カテゴリー変数が入ったカラムを引数にとり、カテゴリーごとに何かしらの集計を行ってくれます。

今回は、平均値を出してみました。集計用の関数はmean以外にもいくつか選択肢があります。とても便利な機能ですが、おろらくRに同様な関数は備わっていないと思われます(勉強不足だったらごめんなさい)。

plot method

DataFrame、Seriesどちらにも、plotというmethodが組み込まれています。 kind引数に、好きなplotのタイプを入れることで様々なplotを描けます。 matplotlibがbackendで動いており、ggplotのような綺麗なplotの作成が可能です。

scatter

例えば、散布図ですと、以下のように書きます。

df.plot(kind="scatter", x="Petal.Length", y="Sepal.Length", title="Scatter plot : Sepal~Petal", figsize=(15,9))

f:id:slmnphmet1-2:20200316140816p:plain

引数xには、x軸に使いたいcolumnの名前を、引数yには、y軸に使いたいcolumnの名前を指定します。引数titleには、plotの上に出力されるグラフのタイトルを、figsizeには、縦✖️横の幅をtuple型で指定します。

histrogram

ヒストグラムを書きたいときは、kind="hist"としましょう。

df.plot(kind="hist", figsize=(14,7), title="Histogram")

Rのhist(df)と異なり、各columnのヒストグラムを一緒の画面に描いてくれます。

f:id:slmnphmet1-2:20200316140831p:plain

他にもたくさんの便利なplotがありますので、興味がある人は、こちらを参照してみて下さい。

note.nkmk.me

要素へのアクセス方法

DataFrameやSeriesの各要素へのアクセス方法についてです。

column, index, name

まず、列名、行名へのアクセスの方法です。 Rの colnames(df) に対応するのは、

df.columns

です。

Index(['Sepal.Length', 'Sepal.Width', 'Petal.Length', 'Petal.Width',
       'Species'],
      dtype='object')

同様に、

Rの rownames(df) に対応するのは、

df.index
Int64Index([  1,   2,   3,   4,   5,   6,   7,   8,   9,  10,
            ...
            141, 142, 143, 144, 145, 146, 147, 148, 149, 150],
           dtype='int64', length=150)

となります。

また、Seriesの名前にアクセスしたいときには、.nameを使います。

df["Sepal.Length"].name
'Sepal.Length'

DataFrame内の要素

行番号/列番号による指定

例えば、Rで1行目の1列目にアクセスしたい時、df[1,1]と書きますが、これに対し、pythonではilocを用いて以下のように書きます。

df.iloc[0,0]

と書きます。 ilocを用いず、df[1,1]のようにしてもエラーを吐くだけなので注意が必要です。

幅を持たせたいとき、例えば、1列目から3列目を取り出したいとき、 Rではdf[,1:3]と書くのに対し、pythonでは、

df.iloc[:, :3]

と書きます。 Rでは、全ての行を取り出したいとき、[,]のカンマの左側に何も入れないのに対し、Pythonではコロンを入れます。

行名/列名による指定

行名、列名で指定したいときには、.loc[行名,列名]を用います。 例えば、個体「1」のPetal.Lengthを知りたいとき、Rではdf[1, "Petal.Length"]とします。これに対しpythonでは、

df.loc[1, "Petal.Length"]

とします。

複数行/複数列で指定したい時は、

df.loc[[1,2], ["Petal.Length", "Species"]]

のようにします。

条件による指定

例えば、Speciesがsetosaである行のみを抜き出したい時、 Rでは、

df[df[,"Species"] == "setosa", ]

のように書きます。 それに対し、pythonでは

df[df["Species"] == "setosa"]

と書きます。また、querymethodを用いて、

df.query("Species == 'setosa'")

とすることも可能です。

querymethodはとても便利で、""の中に、幅広く条件を指定することができます。 例えば、Speciesのcolumnに、'v'という文字を含む箇所だけを取り出したい場合、

df.query("Species.str.contains('v')")

とします。 慣れてくるとquery内の書き方で、様々な条件を指定することができます。 是非マスターしてみましょう。

Series内の要素

DataFrameのアクセス方法と、Seriesがname付きvectorに似ているものという認識が頭に入っていれば、以下も直感的にわかると思います。

行番号による指定

species.iloc[0]

行名による指定

species[1]

もしくは、

species.loc[1]

代入

要素のアクセスの方法が分かっていれば、代入は簡単です。

新しいcolumnを定義しつつ代入

これはRとPythonでほぼ同じです。

df["new_col"] = 0
df.head()
df[,"new_col"] <- 0
head(df)

既存のcolumnに代入

既存のcolumnへの代入は、先ほどとは少々異なります。

行番号/列番号で指定した場所に代入

例えば、new_colの上から5行目までの値を1に変えたい時は、以下のようにします。

df.iloc[:5,5]  = 1
df.head(10)
Sepal.Length Sepal.Width Petal.Length    Petal.Width Species new_col
1   5.1 3.5 1.4 0.2 setosa  1
2   4.9 3.0 1.4 0.2 setosa  1
3   4.7 3.2 1.3 0.2 setosa  1
4   4.6 3.1 1.5 0.2 setosa  1
5   5.0 3.6 1.4 0.2 setosa  1
6   5.4 3.9 1.7 0.4 setosa  0
7   4.6 3.4 1.4 0.3 setosa  0
8   5.0 3.4 1.5 0.2 setosa  0
9   4.4 2.9 1.4 0.2 setosa  0
10  4.9 3.1 1.5 0.1 setosa  0

条件に一致する部分に代入

要素へのアクセス時と同様、条件指定を.loc[]で行い、 =の右辺に代入したい値を書きます。

df.loc[df.Species == 'setosa', "new_col"] = 0
df.head()
Sepal.Length    Sepal.Width Petal.Length    Petal.Width Species new_col
1   5.1 3.5 1.4 0.2 setosa  0
2   4.9 3.0 1.4 0.2 setosa  0
3   4.7 3.2 1.3 0.2 setosa  0
4   4.6 3.1 1.5 0.2 setosa  0
5   5.0 3.6 1.4 0.2 setosa  0

ただし、query methodとの併合はできません。というのも、実はqueryは、条件に一致する新しいDataFrameを作るmethodだからです。

結合

Rのdata.frameとPandasのDataFrameとの間で、 個人的に一番大きいと思われるのが、 結合です。 Pandasを使っていると、改めてRって便利なんだなって思います。

cbind

結合用のDataFrameとして、以下のものを定義します。

df2 = pd.DataFrame([[0]*2]*150, index=[i for i in range(1,151)])
df2.head()
0    1
1   0   0
2   0   0
3   0   0
4   0   0
5   0   0

これを、横方向に結合(Rで言うとcbind)したい場合、

pd.concat([df, df2], axis=1)

とします。 Speciesの右に0と1のcolumnがくっついたはずです。

 Sepal.Length    Sepal.Width Petal.Length    Petal.Width Species 0   1
1   5.1 3.5 1.4 0.2 setosa  0   0
2   4.9 3.0 1.4 0.2 setosa  0   0
3   4.7 3.2 1.3 0.2 setosa  0   0
4   4.6 3.1 1.5 0.2 setosa  0   0
5   5.0 3.6 1.4 0.2 setosa  0   0
... ... ... ... ... ... ... ...
146 6.7 3.0 5.2 2.3 virginica   0   0
147 6.3 2.5 5.0 1.9 virginica   0   0
148 6.5 3.0 5.2 2.0 virginica   0   0
149 6.2 3.4 5.4 2.3 virginica   0   0
150 5.9 3.0 5.1 1.8 virginica   0   0

ただし、index名が異なっていると、こうはいきません。

df2 = pd.DataFrame([[0]*2]*150, index=[i for i in range(0,150)])
pd.concat([df, df2], axis=1)
 Sepal.Length    Sepal.Width Petal.Length    Petal.Width Species 0   1
0   NaN NaN NaN NaN NaN 0.0 0.0
1   5.1 3.5 1.4 0.2 setosa  0.0 0.0
2   4.9 3.0 1.4 0.2 setosa  0.0 0.0
3   4.7 3.2 1.3 0.2 setosa  0.0 0.0
4   4.6 3.1 1.5 0.2 setosa  0.0 0.0
... ... ... ... ... ... ... ...
146 6.7 3.0 5.2 2.3 virginica   0.0 0.0
147 6.3 2.5 5.0 1.9 virginica   0.0 0.0
148 6.5 3.0 5.2 2.0 virginica   0.0 0.0
149 6.2 3.4 5.4 2.3 virginica   0.0 0.0
150 5.9 3.0 5.1 1.8 virginica   NaN NaN

0~150までの151行のindexができます。 片方のDataFrameがもっていない行については、NaNになります。

もし、共通部分を取り出したい時は、join引数に'inner'を指定します(defaultでは'outer')。

pd.concat([df, df2], axis=1, join='inner')
 Sepal.Length    Sepal.Width Petal.Length    Petal.Width Species 0   1
1   5.1 3.5 1.4 0.2 setosa  0   0
2   4.9 3.0 1.4 0.2 setosa  0   0
3   4.7 3.2 1.3 0.2 setosa  0   0
4   4.6 3.1 1.5 0.2 setosa  0   0
5   5.0 3.6 1.4 0.2 setosa  0   0
... ... ... ... ... ... ... ...
145 6.7 3.3 5.7 2.5 virginica   0   0
146 6.7 3.0 5.2 2.3 virginica   0   0
147 6.3 2.5 5.0 1.9 virginica   0   0
148 6.5 3.0 5.2 2.0 virginica   0   0
149 6.2 3.4 5.4 2.3 virginica   0   0

rbind

同様に、縦方向に結合(Rで言うとrbind)したい場合です。 結合用のDataFrameとして、dfdf2を定義し直します。

df = pd.read_csv(path, index_col = 0)
df2 = pd.DataFrame([[1,2,3,4, "hogehoge"],[1,2,3,4, "hogehoge"]], columns=df.columns)
df2.head()
Sepal.Length Sepal.Width Petal.Length    Petal.Width Species
0   1   2   3   4   hogehoge
1   1   2   3   4   hogehoge

dfdf2をrbindの方向にくっつけたい場合、axis=0(default)で行うことができます。

pd.concat([df,df2], axis=0) 
Sepal.Length Sepal.Width Petal.Length    Petal.Width Species
1   5.1 3.5 1.4 0.2 setosa
2   4.9 3.0 1.4 0.2 setosa
3   4.7 3.2 1.3 0.2 setosa
4   4.6 3.1 1.5 0.2 setosa
5   5.0 3.6 1.4 0.2 setosa
... ... ... ... ... ...
148 6.5 3.0 5.2 2.0 virginica
149 6.2 3.4 5.4 2.3 virginica
150 5.9 3.0 5.1 1.8 virginica
0   1.0 2.0 3.0 4.0 hogehoge
1   1.0 2.0 3.0 4.0 hogehoge

最後に

抑えておくべきことをまとめておきます。

  • PandasはRのdata.frameと同様に、テーブル形式のデータを扱えるが、オブジェクト指向であることが大きな違い。
  • RとPythonで似通っている/対応している部分も多い
  • DataFrameはSeriesという名前付きの配列から構成される。
  • Pandasには、Rにはないgroupbyやplotなどの便利なメソッドが満載。
  • DataFrame内の要素にアクセスする時や、結合する時の方法がRと少々異なる。
  • 言語の特性を生かした使い分けができると尚良い。

ご一読ありがとうございました。