将数据框投射到长、删除行、扩展其他行
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,其中 aaa
是 1
并且 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
我也重命名了你的变量,但这显然不重要
我有一个数据框可以转向更长的时间:
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,其中 aaa
是 1
并且 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
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
我也重命名了你的变量,但这显然不重要