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 cookie và Chính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.