繁体   English   中英

Pandas,获取行值的第一列和最后一列索引

[英]Pandas, get first and last column index for row value

我有以下 dataframe:

columns = pd.date_range(start="2022-05-21", end="2022-06-30")
data = [
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5],
    [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
]
df = pd.DataFrame(data, columns=columns)
 2022-05-21  2022-05-22  2022-05-23  ...  2022-06-28  2022-06-29  2022-06-30
0           0           0           0  ...           5           5           5
1           5           5           5  ...           1           1           1
2           5           5           5  ...           5           5           5

我必须按照它们的顺序为每个不同的值获取第一列和最后一列索引。 这个 dataframe 的正确 output 将是:

[
    [
        {'value': 0, 'start': '2022-05-21', 'end': '2022-05-31'}, 
        {'value': 2, 'start': '2022-06-01', 'end': '2022-06-19'}, 
        {'value': 5, 'start': '2022-06-20', 'end': '2022-06-30'}
    ],
    [
        {'value': 5, 'start': '2022-05-21', 'end': '2022-05-31'},
        {'value': 2, 'start': '2022-06-01', 'end': '2022-06-19'},
        {'value': 1, 'start': '2022-06-20', 'end': '2022-06-30'}
    ],
    [
        {'value': 5, 'start': '2022-05-21', 'end': '2022-05-31'},
        {'value': 2, 'start': '2022-06-01', 'end': '2022-06-19'}, 
        {'value': 5, 'start': '2022-06-20', 'end': '2022-06-30'}
    ]
]

我目前最好的方法是:

series_set = df.apply(frozenset, axis=1)
container = []
for index in range(len(df.index)):
    row = df.iloc[[index]]
    values = series_set.iloc[[index]]

    inner_container = []
    for value in values[index]:
        single_value_series = row[row.columns[row.isin([value]).all()]]
        dates = single_value_series.columns
        result = dict(value=value, start=dates[0].strftime("%Y-%m-%d"), end=dates[-1].strftime("%Y-%m-%d"))
        inner_container.append(result)

    container.append(inner_container)

结果是:

[
    [
        {'value': 0, 'start': '2022-05-21', 'end': '2022-05-31'}, 
        {'value': 2, 'start': '2022-06-01', 'end': '2022-06-19'}, 
        {'value': 5, 'start': '2022-06-20', 'end': '2022-06-30'}
    ],
    [
        {'value': 1, 'start': '2022-06-20', 'end': '2022-06-30'}, 
        {'value': 2, 'start': '2022-06-01', 'end': '2022-06-19'}, 
        {'value': 5, 'start': '2022-05-21', 'end': '2022-05-31'}
    ],
    [
        {'value': 2, 'start': '2022-06-01', 'end': '2022-06-19'}, 
        {'value': 5, 'start': '2022-05-21', 'end': '2022-06-30'}
    ]
]

它有几个问题,只有第一个数组是正确的:) 当我将 dataframe 转换为 frozenset 时,它被排序并更改顺序,如果某个值出现不止一次,它也会被删除。

我将不胜感激任何想法和指导。 我想避免的是迭代 dataframe。

谢谢!

您可以先通过DataFrame.T转置DataFrame ,然后聚合最小和最大索引,并通过DataFrame.to_dict将值转换为字符串,最后通过Series.dt.strftime转换为字典。

为了获得连续的组,将移位值与Series.cumsum进行比较。

df1 = df.T.reset_index()
L = [df1.groupby(df1[x].ne(df1[x].shift()).cumsum())
        .agg(value=(x, 'first'),
             start=('index', 'min'),
             end=('index', 'max'))
        .assign(start=lambda x: x['start'].dt.strftime('%Y-%m-%d'),
                end=lambda x: x['end'].dt.strftime('%Y-%m-%d'))
        .to_dict(orient='records') for x in df1.columns.drop('index')]
print (L)
[[{'value': 0, 'start': '2022-05-21', 'end': '2022-05-31'}, 
  {'value': 2, 'start': '2022-06-01', 'end': '2022-06-19'}, 
  {'value': 5, 'start': '2022-06-20', 'end': '2022-06-30'}],
 [{'value': 5, 'start': '2022-05-21', 'end': '2022-05-31'}, 
  {'value': 2, 'start': '2022-06-01', 'end': '2022-06-19'},
  {'value': 1, 'start': '2022-06-20', 'end': '2022-06-30'}],
 [{'value': 5, 'start': '2022-05-21', 'end': '2022-05-31'}, 
  {'value': 2, 'start': '2022-06-01', 'end': '2022-06-19'}, 
  {'value': 5, 'start': '2022-06-20', 'end': '2022-06-30'}]]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM