# DataFrameが等しいことを確認する
## 動機
2つのDataFrameを比較して正しいことを確認する機会があった
## 準備
```python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
```
## NAを含むDataFrameを作成
```python
np.random.seed(0)
df = pd.DataFrame(np.random.random_integers(1, 4, size=(3, 4)), columns=list("abcde"))
df["c"] = np.nan
other = df.copy()
df
```
|
a |
b |
c |
d |
0 |
1 |
4 |
NaN |
1 |
1 |
4 |
4 |
NaN |
4 |
2 |
2 |
4 |
NaN |
3 |
## 各要素が等しいか, DataFrame同士が等しいかを確認
```python
df == other
```
|
a |
b |
c |
d |
0 |
True |
True |
False |
True |
1 |
True |
True |
False |
True |
2 |
True |
True |
False |
True |
```python
np.nan == np.nan, np.nan != np.nan
```
(False, True)
```python
df.equals(other)
```
True
NA同士は等しくない(SQLにおけるNULL)が、DataFrameとしては等しい
## 等しくない場合、どこが等しくないかを確認する
- NAを特定の文字列にし、要素の比較をしたときに等しくなるようにする
- DataFrame同士が等しくないようにするため、otherを変更する
```python
df = df.fillna("NA String")
other = other.fillna("NA String")
other["a"] = 4
other.iloc[0, 1] = 100
other
```
|
a |
b |
c |
d |
0 |
4 |
100 |
NA String |
1 |
1 |
4 |
4 |
NA String |
4 |
2 |
4 |
4 |
NA String |
3 |
```python
# == の method version
eq = df.eq(other)
eq
```
|
a |
b |
c |
d |
0 |
False |
False |
True |
True |
1 |
True |
True |
True |
True |
2 |
False |
True |
True |
True |
```python
df.equals(other)
```
False
- NAであった要素は等しくなっている
- 変更をしたため、DataFrameとしては等しくない
## 等しくないColumnとIndexの特定およびどれくらい等しいか
要素比較結果のDataFrameに対してallをColumnとIndex方向の両方に適用して特定する
```python
pd.DataFrame(eq.all(axis=1))
```
```python
pd.DataFrame(eq.all()).T
```
|
a |
b |
c |
d |
0 |
False |
False |
True |
True |
```python
pd.concat(
[
pd.DataFrame(eq.sum()).T,
pd.DataFrame(eq.sum()).T / len(df)
]
, ignore_index=True)
```
|
a |
b |
c |
d |
0 |
1.000000 |
2.000000 |
3 |
3 |
1 |
0.333333 |
0.666667 |
1 |
1 |
```python
print(pd.options.display.float_format)
with pd.option_context("display.float_format", "{:.2f}%".format):
print(pd.DataFrame(eq.sum()).T / len(df) * 100)
```
None
a b c d
0 33.33% 66.67% 100.00% 100.00%