将数据框投射到长、删除行、扩展其他行

cast data frame to long, dropping rows, expanding others

我有一个数据框可以转向更长的时间:

import pandas as pd
import io

_1 = pd.read_csv(io.StringIO(
    """date;        origin; val_one; val_two; aaa; bbb; ccc; ddd; eee; fff
    10/11/2009;        aaa;       1;       0;   0;   0;   0;   0;   1;   0
    10/11/2009;        bbb;       0;       1;   1;   0;   0;   0;   0;   1
    10/11/2009;        ccc;       0;       1;   0;   0;   0;   0;   0;   0
    10/11/2009;        ddd;       0;       2;   0;   1;   1;   1;   0;   0"""),
    sep=";").set_axis(['date', 'origin', 'val_one', 'val_two',
            'aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff'], axis=1)

我现在想创建 origin-target(行 aaa:fff)二元组。不存在目标的行(即目标列的 none 是 1,例如第三行,索引 2)应该被删除;存在多个目标的行(例如第二行,索引 1,其中 aaa1 并且 fff 是目标列之一是 1)应该转向成两排。预期输出为:

_2_targ = pd.read_csv(io.StringIO(
"""date;        origin; val_one; val_two; target
10/11/2009;        aaa;       1;       0;    eee
10/11/2009;        bbb;       0;       1;    aaa
10/11/2009;        bbb;       0;       1;    fff
10/11/2009;        ddd;       0;       2;    bbb
10/11/2009;        ddd;       0;       2;    ccc
10/11/2009;        ddd;       0;       2;    ddd"""), 
sep=';').set_axis(['date', 'origin', 'val_one', 'val_two', 'target'])

我曾尝试使用 pd.melt 但无济于事(见下文)- 这会创建 all 对偶,甚至是我不想保留的对偶(因为没有目标列是 1).

_2 = pd.melt(_1,
             id_vars=['date', 'origin', 'val_one', 'val_two'],
             value_vars=['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff'],
             var_name='target', value_name='tmp')

我错过了什么?

我相信你可以像你现在做的那样融化,然后从 long_df 中删除 tmp

值为 0 的行
import pandas as pd
import io

#nice reproducible input!
df1 = pd.read_csv(io.StringIO(
    """date;        origin; val_one; val_two; aaa; bbb; ccc; ddd; eee; fff
    10/11/2009;        aaa;       1;       0;   0;   0;   0;   0;   1;   0
    10/11/2009;        bbb;       0;       1;   1;   0;   0;   0;   0;   1
    10/11/2009;        ccc;       0;       1;   0;   0;   0;   0;   0;   0
    10/11/2009;        ddd;       0;       2;   0;   1;   1;   1;   0;   0"""),
    sep=";").set_axis(['date', 'origin', 'val_one', 'val_two',
            'aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff'], axis=1)

#Melt exactly the same as you did
long_df = pd.melt(
    df1,
    id_vars=['date', 'origin', 'val_one', 'val_two'],
    value_vars=['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff'],
    var_name='target', value_name='tmp'
)

#Filter out rows where tmp is 0, sort to match your output, and drop the tmp column
long_df = long_df[long_df['tmp'].gt(0)].sort_values('origin').drop(columns='tmp').reset_index(drop=True)
long_df

输出几乎如上所示,但我认为您忘记了 bbb:fff

             date       origin  val_one  val_two target
0      10/11/2009          aaa        1        0    eee
1      10/11/2009          bbb        0        1    aaa
2      10/11/2009          bbb        0        1    fff
3      10/11/2009          ddd        0        2    bbb
4      10/11/2009          ddd        0        2    ccc
5      10/11/2009          ddd        0        2    ddd

我也重命名了你的变量,但这显然不重要