Hướng dẫn python irr with dates - python irr với ngày tháng

Một cách để đi về điều này là tham gia các luồng và quan sát để có được các hiệp hội, sau đó nhóm theo ngày quan sát và ID đầu tư để có được mỗi nhóm mà chúng tôi quan tâm.

Hàm process_df được UED để lọc ra chỉ vài ngày trước ngày quan sát (DATE_y).

Lấy đầu tư giá trị, ngày quan sát (DATE_y) và giá trị cổ phiếu từ hàng đầu tiên vì tất cả đều giống nhau trong nhóm và nối vào cuối bảng của bạn. Sau đó, chỉ cần dọn dẹp mọi thứ thả các cột bổ sung (stock và date_y), đặt lại chỉ mục và đổi tên các cột để phản ánh đầu ra mong muốn của bạn.

import pandas as pd

flows = pd.DataFrame({'DATE': {0: '2012-05-12', 1: '2013-09-04',
                               2: '2014-05-05', 3: '2013-09-04',
                               4: '2015-05-12', 5: '2012-04-04',
                               6: '2013-05-12', 7: '2013-09-04',
                               8: '2020-05-12', 9: '2016-07-12'},
                      'Investment': {0: 1, 1: 1, 2: 1, 3: 2,
                                     4: 2, 5: 3, 6: 3, 7: 4,
                                     8: 5, 9: 7},
                      'Flow': {0: -50, 1: 100, 2: 300, 3: -700,
                               4: 1000, 5: 100, 6: -50, 7: -60,
                               8: 100, 9: 800}})
flows['DATE'] = flows['DATE'].astype('datetime64[ns]')

observations = pd.DataFrame({'DATE': {0: '2012-09-05', 1: '2014-05-05',
                                      2: '2014-05-05', 3: '2013-09-04',
                                      4: '2012-09-14', 5: '2013-09-05',
                                      6: '2014-05-14', 7: '2015-12-14'},
                             'Investment': {0: 1, 1: 1, 2: 2,
                                            3: 2, 4: 3, 5: 4,
                                            6: 5, 7: 6},
                             'Stock': {0: 400, 1: 600, 2: 300,
                                       3: 800, 4: 1000, 5: 6000,
                                       6: 0, 7: 15}})
observations['DATE'] = observations['DATE'].astype('datetime64[ns]')


def process_df(df):
    out = df[df['DATE_x'] <= df['DATE_y']]  # Filter Out Out of Bound Dates
    if out.empty:
        # Handle Case Where Observation but No flows
        return df[['DATE_y', 'Investment', 'Stock']] \
            .reset_index(drop=True) \
            .rename(columns={'DATE_y': 'DATE', 'Stock': 'Flow + Stock(last row)'})
    return out.drop(['DATE_y', 'Stock'], axis=1) \
        .append(out[['Investment', 'DATE_y', 'Stock']]
                .iloc[0]
                .rename({'DATE_y': 'DATE_x', 'Stock': 'Flow'})) \
        .reset_index(drop=True) \
        .rename(columns={'DATE_x': 'DATE', 'Flow': 'Flow + Stock(last row)'})


merged = pd.merge(flows, observations, on='Investment', how='right')

dfs = [process_df(group) for _, group in merged.groupby(['Investment', 'DATE_y'])]

# For Display
for i, new_df in enumerate(dfs):
    print(f'DataFrame {i+1}')
    print(new_df)
    print()

DFS là một danh sách chứa các khung dữ liệu riêng lẻ.

Output:

DataFrame 1
        DATE  Investment  Flow + Stock(last row)
0 2012-05-12           1                   -50.0
1 2012-09-05           1                   400.0

DataFrame 2
        DATE  Investment  Flow + Stock(last row)
0 2012-05-12           1                   -50.0
1 2013-09-04           1                   100.0
2 2014-05-05           1                   300.0
3 2014-05-05           1                   600.0

DataFrame 3
        DATE  Investment  Flow + Stock(last row)
0 2013-09-04           2                  -700.0
1 2013-09-04           2                   800.0

DataFrame 4
        DATE  Investment  Flow + Stock(last row)
0 2013-09-04           2                  -700.0
1 2014-05-05           2                   300.0

DataFrame 5
        DATE  Investment  Flow + Stock(last row)
0 2012-04-04           3                   100.0
1 2012-09-14           3                  1000.0

DataFrame 6
        DATE  Investment  Flow + Stock(last row)
0 2013-09-04           4                   -60.0
1 2013-09-05           4                  6000.0

DataFrame 7
        DATE  Investment  Flow + Stock(last row)
0 2014-05-14           5                       0

DataFrame 8
        DATE  Investment  Flow + Stock(last row)
0 2015-12-14           6                      15

Chỉnh sửa ghi chú:

  • Việc thực hiện ban đầu của tôi đã đưa ra một giả định sai rằng tất cả các quan sát sẽ có ít nhất một luồng. Tôi đã đoán xem cách bạn muốn nhận thông tin về các quan sát không có liên kết dòng chảy và chọn trả lại một khung dữ liệu vẫn có hàng cuối cùng với thông tin chứng khoán nhưng không có luồng. Nếu bạn thích một DataFrame trống thay vào đó, xin vui lòng quay lại.
    if out.empty:
        # Handle Case Where Observation but No flows
        return out
  • Tôi đã thêm 3 trường hợp thử nghiệm bổ sung vào dữ liệu mẫu.
    1. Có một dòng chảy, nhưng nó xảy ra sau khi quan sát
    2. Không có luồng cho một ID đầu tư nhất định
    3. Có một dòng chảy nhưng không có quan sát.
      • Cho rằng các khung dữ liệu được tạo của bạn dựa trên các quan sát, tôi đã chọn loại trừ các luồng không phù hợp trong các quan sát bằng cách sử dụng tham gia 'đúng'.