Làm cách nào để thay đổi hiệu quả bố cục dữ liệu của DataFrame trong gấu trúc?


8

Tôi đã có một DataFrame với các giá trị được sắp xếp trong hai cột, xem bảng T1 . Muốn sắp xếp lại các giá trị theo cách tạo bố cục dữ liệu như trong bảng T2 . Các hàng trong T2 được tạo bằng cách hoán chuyển "cửa sổ trượt" của các giá trị, di chuyển xuống cột a trong bảng T1 . Có một số cách thông minh trong gấu trúc để làm điều này một cách hiệu quả?

T1              T2

 a | b           A |  B |  C | D
------          ---------------
41 | 5          41 | 42 | 43 | 7
42 | 6          42 | 43 | 44 | 8
43 | 7    -->   43 | 44 | 45 | 9
44 | 8          44 | 45 | .. | .
45 | 9          45 | .. | .. | .
.. | .          .. | .. | .. | .
.. | .          .. | .. | .. | .

Câu trả lời:


5

Bạn có thể sử dụng as_strided:

from numpy.lib.stride_tricks import as_strided

window = 3
stride = df['a'].values.strides[0]

pd.DataFrame(as_strided(df['a'].values, 
                        shape=(len(df) - window + 1, window),
                        strides = (stride,stride))
            )

Đầu ra:

     0   1   2
0   41  42  43
1   42  43  44
2   43  44  45

4

Cái này cần phải dùng mẹo:

df = df.rename(columns={"b": "D", "a": "A"})

df["B"] = df["A"].shift(-1)
df["C"] = df["A"].shift(-2)
df["D"] = df["D"].shift(-2)
df = df.sort_index(axis=1)

Đầu ra:

    A     B     C    D
0  41  42.0  43.0  7.0
1  42  43.0  44.0  8.0
2  43  44.0  45.0  9.0
3  44  45.0   NaN  NaN
4  45   NaN   NaN  NaN

3

Bạn có thể sử dụng as_strided:

stride = np.lib.stride_tricks.as_strided
window=3
v = stride(df.a, (len(df) - (window - 1), window), (df.a.values.strides * 2))
df=df.assign(**pd.DataFrame(v.tolist(),columns=list('ABC')).reindex(df.index))
df=df.assign(D=df.iloc[:,-1].map(df.set_index('a')['b']))
print(df)

    a  b     A     B     C    D
0  41  5  41.0  42.0  43.0  7.0
1  42  6  42.0  43.0  44.0  8.0
2  43  7  43.0  44.0  45.0  9.0
3  44  8   NaN   NaN   NaN  NaN
4  45  9   NaN   NaN   NaN  NaN

2

Bạn có thể sử dụng lập chỉ mục numpy:

window = 3
indexer = np.arange(window)[None, :] + np.arange(len(df) - window + 1)[:, None]
a_values = df.a.values[indexer]  # apply fancy indexing on a

b_values = df.b.values[window - 1:].reshape(-1, 1)

result = pd.DataFrame(data=np.hstack([a_values, b_values]), columns=['A', 'B', 'C', 'D'])

print(result)

Đầu ra

    A   B   C  D
0  41  42  43  7
1  42  43  44  8
2  43  44  45  9
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.