python - 基于输入行的 pandas long_to_wide 方法
问题描述
我在删除空值时遇到问题。我的输入数据框
name no city tr1_0 tr2_0 tr3_0 tr1_1 tr2_1 tr3_1 tr1_2 tr2_2 tr3_2
John 11 edi boa 51 110 cof 52 220
Rick 12 new cof 61 100 dcu 61 750
Mat t1 nyc
我想要的输出
name no city tr1 tr3 tr2
0 John 11 edi boa 110 51
1 John 11 edi cof 220 52
2 Rick 12 new cof 100 61
3 Rick 12 new dcu 750 61
4 Matt 13 wil nan nan nan
我用下面的代码
df1 = pd.read_fwf(inputFileName, widths=widths, names=names, dtype=str, index_col=False )
feature_models = [col for col in df1.columns if re.match("tr[0-9]_[0-9]",col) is not None]
features = list(set([ re.sub("_[0-9]","",feature_model) for feature_model in feature_models]))
ub("_[0-9]","",feature_model) for feature_model in feature_models]))
df1 = pd.wide_to_long(df1,i=['name', 'no',
df1 = pd.wide_to_long(df1,i=['name', 'no', 'city',],j='ModelID',stubnames=features,sep="_")
我当前的输出如下。第 2 行在我的用例中没有任何意义,所以我根本不想生成该行。如果没有拖车,我只想要 1 行,这很好(第 6 行)。如果有 2 个拖车,我只想要 2 行,但它给了我 3 行。(第 2 行和第 5 行是额外的)。我尝试使用 dropna 但它不起作用。同样在我的情况下,它的打印为 nan 而不是 NaN。
name no city tr1 tr3 tr2
0 John 11 edi boa 110 51 .
1 John 11 edi cof 220 52 .
2 John 11 edi nan nan nan .
3 Rick 12 new cof 100 61 .
4 Rick 12 new dcu 750 61 .
5 Rick 12 new nan nan nan .
6 Matt 13 wil nan nan nan .
解决方案
您可以将此替代解决方案与split
and一起使用stack
:
df1 = df1.set_index(['name', 'no', 'city'])
df1.columns = df1.columns.str.split('_', expand=True)
df1 = df1.stack(1, dropna=False).reset_index(level=3, drop=True)
mask = df1.index.duplicated() & df1.isnull().all(axis=1)
df1 = df1[~mask].reset_index()
print (df1)
name no city tr1 tr2 tr3
0 John 11 edi boa 51.0 110.0
1 John 11 edi cof 52.0 220.0
2 Rick 12 new cof 61.0 100.0
3 Rick 12 new dcu 61.0 750.0
4 Mat t1 nyc NaN NaN NaN
使用您的解决方案:
df1 = pd.wide_to_long(df1,i=['name', 'no', 'city'],j='ModelID',stubnames=features,sep="_")
对于删除NaN
具有重复MultiIndex
值的 s,可以使用以下过滤boolean indexing
:
#remove counting level
df1 = df1.reset_index(level=3, drop=True)
mask = df1.index.duplicated() & df1.isnull().all(axis=1)
df1 = df1[~mask].reset_index()
详情:
通过以下方式检查受骗者Index.duplicated
:
print (df1.index.duplicated())
[False True False True False True]
DataFrame.all
然后通过for 检查True
每行的所有 s检查缺失值:
print (df1.isnull().all(axis=1))
name no city
John 11 edi False
edi False
Rick 12 new False
new False
Mat t1 nyc True
nyc True
dtype: bool
通过&
for链接bitwise AND
:
mask = df1.index.duplicated() & df1.isnull().all(axis=1)
print (mask)
name no city
John 11 edi False
edi False
Rick 12 new False
new False
Mat t1 nyc False
nyc True
dtype: bool
反转布尔掩码~
:
print (~mask)
name no city
John 11 edi True
edi True
Rick 12 new True
new True
Mat t1 nyc True
nyc False
dtype: bool
推荐阅读
- php - PHP 7.4.8 仅针对特定脚本的最大执行时间
- .net - mgcb 编辑器 (monogame) 无法启动或下载
- javascript - 如何将不带引号的数据从我的网站添加到 Firebase
- azure - 如何从 DataBricks 中删除自动化集群?
- mapbox - 如何旋转 Mapbox 中 geoJSON 指定的图标?
- c++ - 为什么可以在 C++ 中使用没有#include 线程的 std::thread ?
- javascript - 让 React 与生产环境中不同 EC2 实例上的后端 API 服务器对话
- spring-webflux - 有没有办法修改 Spring 创建的默认协程上下文?
- fs - 如何使用 javascript 通过 nexe 访问已编译的 .exe 中的捆绑文件
- javascript - 从导入的 .obj 模型中拖动顶点