zmc
2023-12-22 9fdbf60165db0400c2e8e6be2dc6e88138ac719a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import numpy as np
import pytest
 
from pandas import (
    DataFrame,
    Series,
)
import pandas._testing as tm
 
 
class TestDataFramePctChange:
    @pytest.mark.parametrize(
        "periods,fill_method,limit,exp",
        [
            (1, "ffill", None, [np.nan, np.nan, np.nan, 1, 1, 1.5, 0, 0]),
            (1, "ffill", 1, [np.nan, np.nan, np.nan, 1, 1, 1.5, 0, np.nan]),
            (1, "bfill", None, [np.nan, 0, 0, 1, 1, 1.5, np.nan, np.nan]),
            (1, "bfill", 1, [np.nan, np.nan, 0, 1, 1, 1.5, np.nan, np.nan]),
            (-1, "ffill", None, [np.nan, np.nan, -0.5, -0.5, -0.6, 0, 0, np.nan]),
            (-1, "ffill", 1, [np.nan, np.nan, -0.5, -0.5, -0.6, 0, np.nan, np.nan]),
            (-1, "bfill", None, [0, 0, -0.5, -0.5, -0.6, np.nan, np.nan, np.nan]),
            (-1, "bfill", 1, [np.nan, 0, -0.5, -0.5, -0.6, np.nan, np.nan, np.nan]),
        ],
    )
    def test_pct_change_with_nas(
        self, periods, fill_method, limit, exp, frame_or_series
    ):
        vals = [np.nan, np.nan, 1, 2, 4, 10, np.nan, np.nan]
        obj = frame_or_series(vals)
 
        res = obj.pct_change(periods=periods, fill_method=fill_method, limit=limit)
        tm.assert_equal(res, frame_or_series(exp))
 
    def test_pct_change_numeric(self):
        # GH#11150
        pnl = DataFrame(
            [np.arange(0, 40, 10), np.arange(0, 40, 10), np.arange(0, 40, 10)]
        ).astype(np.float64)
        pnl.iat[1, 0] = np.nan
        pnl.iat[1, 1] = np.nan
        pnl.iat[2, 3] = 60
 
        for axis in range(2):
            expected = pnl.ffill(axis=axis) / pnl.ffill(axis=axis).shift(axis=axis) - 1
            result = pnl.pct_change(axis=axis, fill_method="pad")
 
            tm.assert_frame_equal(result, expected)
 
    def test_pct_change(self, datetime_frame):
        rs = datetime_frame.pct_change(fill_method=None)
        tm.assert_frame_equal(rs, datetime_frame / datetime_frame.shift(1) - 1)
 
        rs = datetime_frame.pct_change(2)
        filled = datetime_frame.fillna(method="pad")
        tm.assert_frame_equal(rs, filled / filled.shift(2) - 1)
 
        rs = datetime_frame.pct_change(fill_method="bfill", limit=1)
        filled = datetime_frame.fillna(method="bfill", limit=1)
        tm.assert_frame_equal(rs, filled / filled.shift(1) - 1)
 
        rs = datetime_frame.pct_change(freq="5D")
        filled = datetime_frame.fillna(method="pad")
        tm.assert_frame_equal(
            rs, (filled / filled.shift(freq="5D") - 1).reindex_like(filled)
        )
 
    def test_pct_change_shift_over_nas(self):
        s = Series([1.0, 1.5, np.nan, 2.5, 3.0])
 
        df = DataFrame({"a": s, "b": s})
 
        chg = df.pct_change()
        expected = Series([np.nan, 0.5, 0.0, 2.5 / 1.5 - 1, 0.2])
        edf = DataFrame({"a": expected, "b": expected})
        tm.assert_frame_equal(chg, edf)
 
    @pytest.mark.parametrize(
        "freq, periods, fill_method, limit",
        [
            ("5B", 5, None, None),
            ("3B", 3, None, None),
            ("3B", 3, "bfill", None),
            ("7B", 7, "pad", 1),
            ("7B", 7, "bfill", 3),
            ("14B", 14, None, None),
        ],
    )
    def test_pct_change_periods_freq(
        self, datetime_frame, freq, periods, fill_method, limit
    ):
        # GH#7292
        rs_freq = datetime_frame.pct_change(
            freq=freq, fill_method=fill_method, limit=limit
        )
        rs_periods = datetime_frame.pct_change(
            periods, fill_method=fill_method, limit=limit
        )
        tm.assert_frame_equal(rs_freq, rs_periods)
 
        empty_ts = DataFrame(index=datetime_frame.index, columns=datetime_frame.columns)
        rs_freq = empty_ts.pct_change(freq=freq, fill_method=fill_method, limit=limit)
        rs_periods = empty_ts.pct_change(periods, fill_method=fill_method, limit=limit)
        tm.assert_frame_equal(rs_freq, rs_periods)
 
 
@pytest.mark.parametrize("fill_method", ["pad", "ffill", None])
def test_pct_change_with_duplicated_indices(fill_method):
    # GH30463
    data = DataFrame(
        {0: [np.nan, 1, 2, 3, 9, 18], 1: [0, 1, np.nan, 3, 9, 18]}, index=["a", "b"] * 3
    )
    result = data.pct_change(fill_method=fill_method)
    if fill_method is None:
        second_column = [np.nan, np.inf, np.nan, np.nan, 2.0, 1.0]
    else:
        second_column = [np.nan, np.inf, 0.0, 2.0, 2.0, 1.0]
    expected = DataFrame(
        {0: [np.nan, np.nan, 1.0, 0.5, 2.0, 1.0], 1: second_column},
        index=["a", "b"] * 3,
    )
    tm.assert_frame_equal(result, expected)