記事ディレクトリ
ジョイフルパンダ
Datawhale コミュニティのJoyful Pandasコースにおける接続、グループ化、集約の構成:
接続する
関係的なつながり
- 左結合: 左 - 右
- 右結合: 右 - 左
- 内部結合: 左右のテーブルで同じキーを保持します。
- 外部結合: 左右のテーブルにすべてのキーを保持します。
列結合
df1.merge(df2, left_index = True, right_index = True)
インデックス結合
df1.join(df2)
縦のつながり
df1.append(df2)
# 同pd.concat([df1, df2], axis = 1)
方向接続
pd.concat([df1, df2], axis = 0)
df1.assign(s1)
# dataframe 末尾追加 series
グループ化スキーマとそのオブジェクト
グループモード
df.groupby(分组依据)[数据来源].具体操作
グループ化オブジェクト
gb = df.groupby([..., ...]
- 属性
- ngroups: グループの数
- グループ: グループ名のマッピングの辞書
- 方法
- size(): 各グループ内の要素の数をカウントします。
- get_group(): 要素が配置されているグループに対応する行を取得します。
集計関数
df.agg()
実践的なデータ分析
Datawhale コミュニティの実践的なデータ分析コースのデータ再構築に関するコンテンツ:
開始する前に、numpy、pandas のパッケージとデータをインポートします
# 导入基本库
import numpy as np
import pandas as pd
# 载入data文件中的:train-left-up.csv
pd.read_csv("data/train-left-up.csv").head()
乗客ID | 生き残った | Pクラス | 名前 | |
---|---|---|---|---|
0 | 1 | 0 | 3 | ブラウン、オーウェン・ハリス氏 |
1 | 2 | 1 | 1 | カミングス、ジョン・ブラッドリー夫人 (フローレンス・ブリッグス・... |
2 | 3 | 1 | 3 | ヘイキネンさん、ローン |
3 | 4 | 1 | 1 | フットレル、ジャック・ヒース夫人(リリー・メイ・ピール) |
4 | 5 | 0 | 3 | アレン、ウィリアム・ヘンリー氏 |
2 第 2 章: データの再構築
2.4 データの結合
2.4.1 タスク 1
データフォルダー内のすべてのデータをロードし、データ間の関係を観察します。
#写入代码
text_left_up = pd.read_csv("data/train-left-up.csv")
text_left_down = pd.read_csv("data/train-left-down.csv")
text_right_up = pd.read_csv("data/train-right-up.csv")
text_right_down = pd.read_csv("data/train-right-down.csv")
#写入代码
my_list = [text_left_up, text_left_down, text_right_up, text_right_down]
for i in my_list:
print(i.info())
print('=========')
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 439 entries, 0 to 438
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 439 non-null int64
1 Survived 439 non-null int64
2 Pclass 439 non-null int64
3 Name 439 non-null object
dtypes: int64(3), object(1)
memory usage: 13.8+ KB
None
=========
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 452 entries, 0 to 451
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 452 non-null int64
1 Survived 452 non-null int64
2 Pclass 452 non-null int64
3 Name 452 non-null object
dtypes: int64(3), object(1)
memory usage: 14.2+ KB
None
=========
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 439 entries, 0 to 438
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Sex 439 non-null object
1 Age 352 non-null float64
2 SibSp 439 non-null int64
3 Parch 439 non-null int64
4 Ticket 439 non-null object
5 Fare 439 non-null float64
6 Cabin 97 non-null object
7 Embarked 438 non-null object
dtypes: float64(2), int64(2), object(4)
memory usage: 27.6+ KB
None
=========
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 452 entries, 0 to 451
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Sex 452 non-null object
1 Age 362 non-null float64
2 SibSp 452 non-null int64
3 Parch 452 non-null int64
4 Ticket 452 non-null object
5 Fare 452 non-null float64
6 Cabin 107 non-null object
7 Embarked 451 non-null object
dtypes: float64(2), int64(2), object(4)
memory usage: 28.4+ KB
None
=========
[ヒント] 先ほどロードしたtrain.csvデータと組み合わせると、上記のデータがどのようなものであるかを大まかに予測できます。
2.4.2: タスク 2
concat メソッドを使用します。データ train-left-up.csv と train-right-up.csv を水平方向に 1 つのテーブルにマージし、このテーブルを result_up として保存します。
#写入代码
result_up = pd.concat([text_left_up, text_right_up], axis = 1)
result_up.head()
乗客ID | 生き残った | Pクラス | 名前 | セックス | 年 | シブスプ | 尊敬 | チケット | 運賃 | キャビン | 乗り出しました | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 3 | ブラウン、オーウェン・ハリス氏 | 男 | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
1 | 2 | 1 | 1 | カミングス、ジョン・ブラッドリー夫人 (フローレンス・ブリッグス・... | 女性 | 38.0 | 1 | 0 | PC17599 | 71.2833 | C85 | C |
2 | 3 | 1 | 3 | ヘイキネンさん、ローン | 女性 | 26.0 | 0 | 0 | ストン/O2。3101282 | 7.9250 | NaN | S |
3 | 4 | 1 | 1 | フットレル、ジャック・ヒース夫人(リリー・メイ・ピール) | 女性 | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
4 | 5 | 0 | 3 | アレン、ウィリアム・ヘンリー氏 | 男 | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S |
2.4.3 タスク 3
concat メソッドを使用します。train-left-down と train-right-down を水平方向に 1 つのテーブルにマージし、このテーブルを result_down として保存します。次に、上記の result_up と result_down を result に垂直方向にマージします。
#写入代码
result_down = pd.concat([text_left_down, text_right_down], axis = 1)
result_down.head()
乗客ID | 生き残った | Pクラス | 名前 | セックス | 年 | シブスプ | 尊敬 | チケット | 運賃 | キャビン | 乗り出しました | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 440 | 0 | 2 | クヴィルナーさん、ヨハン・ヘンリック・ヨハネソン | 男 | 31.0 | 0 | 0 | CA 18723 | 10.500 | NaN | S |
1 | 441 | 1 | 2 | ハート、ベンジャミン夫人 (エスター・エイダ・ブルームフィールド) | 女性 | 45.0 | 1 | 1 | FCC 13529 | 26.250 | NaN | S |
2 | 442 | 0 | 3 | 麻さん、レオン | 男 | 20.0 | 0 | 0 | 345769 | 9.500 | NaN | S |
3 | 443 | 0 | 3 | ペターソン、ヨハン・エミル氏 | 男 | 25.0 | 1 | 0 | 347076 | 7.775 | NaN | S |
4 | 444 | 1 | 2 | レイナルド、エンカルナシオンさん | 女性 | 28.0 | 0 | 0 | 230434 | 13.000 | NaN | S |
result = pd.concat([result_up, result_down], axis = 0).reset_index(drop = True)
result.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 891 non-null int64
1 Survived 891 non-null int64
2 Pclass 891 non-null int64
3 Name 891 non-null object
4 Sex 891 non-null object
5 Age 714 non-null float64
6 SibSp 891 non-null int64
7 Parch 891 non-null int64
8 Ticket 891 non-null object
9 Fare 891 non-null float64
10 Cabin 204 non-null object
11 Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KB
2.4.4 タスク 4
DataFrame に付属するメソッド join メソッドと append を使用して、タスク 2 とタスク 3 のタスクを完了します。
#写入代码
resul_up = text_left_up.join(text_right_up)
result_down = text_left_down.join(text_right_down)
result = result_up.append(result_down).reset_index(drop = True)
result.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 891 non-null int64
1 Survived 891 non-null int64
2 Pclass 891 non-null int64
3 Name 891 non-null object
4 Sex 891 non-null object
5 Age 714 non-null float64
6 SibSp 891 non-null int64
7 Parch 891 non-null int64
8 Ticket 891 non-null object
9 Fare 891 non-null float64
10 Cabin 204 non-null object
11 Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KB
2.4.5 タスク 5
Panads の merge メソッドと DataFrame の append メソッドを使用して、タスク 2 とタスク 3 のタスクを完了します。
#写入代码
resul_up = text_left_up.merge(text_right_up, left_index = True, right_index = True)
result_down = text_left_down.merge(text_right_down, left_index = True, right_index = True)
result = result_up.append(result_down).reset_index(drop = True)
result.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 891 non-null int64
1 Survived 891 non-null int64
2 Pclass 891 non-null int64
3 Name 891 non-null object
4 Sex 891 non-null object
5 Age 714 non-null float64
6 SibSp 891 non-null int64
7 Parch 891 non-null int64
8 Ticket 891 non-null object
9 Fare 891 non-null float64
10 Cabin 204 non-null object
11 Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KB
[考え方] merge、join、concat の方法の違いと類似点を比較します。DataFrame の append メソッドを使用するためにタスク 4 と 5 が必要な理由を考えてください。タスク 4 と 5 を完了するためにマージまたは結合しか使用できないのはなぜでしょうか。
merge、join は列の結合に使用され、append は行の結合に使用されます。公式ドキュメント:
pandas.DataFrame.join
pandas.DataFrame.merge
pandas.DataFrame.append
2.5 データを別の角度から見る
2.5.1 タスク 1
データをシリーズ データに変換する
#写入代码
result.stack().shape
(9826,)
#写入代码
result.stack()[0]
PassengerId 1
Survived 0
Pclass 3
Name Braund, Mr. Owen Harris
Sex male
Age 22.0
SibSp 1
Parch 0
Ticket A/5 21171
Fare 7.25
Embarked S
dtype: object
復習:前章で Pandas の基礎を学びました。第 2 章では、データ分析のビジネス部分に入り始めました。第 2 章の最初のセクションの内容では、データ クリーニングについて学びました。この部分データが比較的クリーンになって初めて、データをより強力に分析できるようになります。このセクションでは、データの再構築を行いますが、これはまだデータの理解 (準備) の範囲に属します。
2.6 データ活用
2.6.1 タスク 1
GroupBy メカニズムについては、教科書「データ分析のための Python」P303、Google などで学習してください。
#写入心得
2.4.2: タスク 2
タイタニック号の男性と女性の平均運賃を計算してください
# 写入代码
df.groupby('Sex')['Fare'].mean()
Sex
female 44.479818
male 25.523893
Name: Fare, dtype: float64
GroupBy メカニズムを理解した後、このメカニズムを使用して一連の操作を完了し、目的を達成します。
いくつかのタスクを通じて、GroupBy メカニズムに慣れてみましょう。
2.4.3: タスク 3
タイタニック号で生き残った男女の数を数えてください
# 写入代码
df.groupby('Sex')['Survived'].sum()
Sex
female 233
male 109
Name: Survived, dtype: int64
2.4.4: タスク 4
さまざまなクラスの客室の生存者の数を計算します
# 写入代码
df.groupby('Pclass')['Survived'].sum()
Pclass
1 136
2 87
3 119
Name: Survived, dtype: int64
【補足】 countとsumメソッドの違いについて
count count→何行、sum累計→0、1の数を求めるためにラベルを1つ追加します。
print(df.groupby('Pclass')['Survived'].count())
print('=========')
df.Pclass.value_counts()
Pclass
1 216
2 184
3 491
Name: Survived, dtype: int64
=========
3 491
1 216
2 184
Name: Pclass, dtype: int64
[ヒント: ] 表の生存欄では、生存している場合は 1、死亡している場合は 0 と記録されることがわかります。
[考え方] データ分析の観点から、上記の統計結果からどのような結論が導き出せるか
#思考体験
- 女性は男性よりも平均して運賃が高い
- 女性は男性よりもはるかに長く生き残る
- 客室クラス 1 では生存確率が高い
[考え方] タスク 2 からタスク 3 まで、これらの操作は agg() 関数によって同時に計算できます。また、名前変更関数を使用して列名を変更できます。プロンプトに従ってプロセスを書き留めることはできますか?
#思考心得
df.groupby('Sex').agg({
'Fare': 'mean', 'Survived': 'sum'}).rename(columns = {
'Fare': 'Fare_mean', 'Survived': 'Survived_sum'})
運賃_平均値 | Survived_sum | |
---|---|---|
セックス | ||
女性 | 44.479818 | 233 |
男 | 25.523893 | 109 |
2.4.5: タスク 5
さまざまなクラスのチケットにおけるさまざまな年齢のチケットの平均コストの統計
# 写入代码
df['Age_level'] = pd.cut(df.Age, bins = 4)
df.groupby(['Pclass','Age_level'])['Fare'].mean()
Pclass Age_level
1 (0.34, 20.315] 116.136705
(20.315, 40.21] 97.959878
(40.21, 60.105] 70.386898
(60.105, 80.0] 59.969050
2 (0.34, 20.315] 24.725834
(20.315, 40.21] 21.055769
(40.21, 60.105] 20.254032
(60.105, 80.0] 10.500000
3 (0.34, 20.315] 16.580693
(20.315, 40.21] 11.402144
(40.21, 60.105] 12.248931
(60.105, 80.0] 7.820000
Name: Fare, dtype: float64
2.4.6: タスク 6
タスク2とタスク3のデータを結合し、sex_fare_survived.csvに保存します。
# 写入代码
pd.concat([df.groupby('Sex')['Fare'].mean(), df.groupby('Sex')['Survived'].sum()], axis = 1)
運賃 | 生き残った | |
---|---|---|
セックス | ||
女性 | 44.479818 | 233 |
男 | 25.523893 | 109 |
pd.merge(df.groupby('Sex')['Fare'].mean(), df.groupby('Sex')['Survived'].sum(),on='Sex')
運賃 | 生き残った | |
---|---|---|
セックス | ||
女性 | 44.479818 | 233 |
男 | 25.523893 | 109 |
2.4.7: タスク 7
さまざまな年齢の生存者の合計数を取得し、次に生存者の数が最も多い年齢層を見つけ、最後に生存者の数が最も多い生存率 (生存者の数/総数) を計算します。
# 写入代码
survived_age = df.groupby('Age')['Survived'].sum()
# 写入代码
survived_age.sort_values(ascending= False)
Age
24.0 15
22.0 11
27.0 11
36.0 11
35.0 11
..
20.5 0
23.5 0
24.5 0
28.5 0
40.5 0
Name: Survived, Length: 88, dtype: int64
survived_age.sort_values(ascending= False).iloc[0] / df.Survived.sum()
0.043859649122807015