Python 将dataframe列标题复制到数据的标签
摘要:代码的输出为我提供了以下格式的数据帧。数据框的列标题是列Python 将dataframe列标题复制到数据的标签,python,python-3.x,pandas,csv,dataframe,Python,Python 3.x,Pandas,Csv,Dataframe,摘要:代码的输出为我提供了以下格式的数据帧。数据框的列标题是列Content中文本的标签。在下一步中,标签将用作多标签分类器的训练数据。这是一个更大的实际数据片段 由于它们是列标题,因此无法将它们映射到作为标签的文本 Content A B C D E zxy 1 2 1 wvu 1 2 1 tsr 1 2 2 qpo 1 1 1 nml 2 2
Content
中文本的标签。在下一步中,标签将用作多标签分类器的训练数据。这是一个更大的实际数据片段
由于它们是列标题,因此无法将它们映射到作为标签的文本
Content A B C D E
zxy 1 2 1
wvu 1 2 1
tsr 1 2 2
qpo 1 1 1
nml 2 2
kji 1 1 2
hgf 1 2
edc 1 2 1
更新:将df转换为csv显示空单元格为空('
vs'
):
其中,Content
是文本所在的列,A
、B
、C
、D
和E
是需要转换为标签的列标题。只有带1或2的列才相关。带有空单元格的列不相关,因此不需要转换为标签
更新:经过一些挖掘,可能数字不是整数,而是字符串
我知道,当将文本+标签输入分类器进行处理时,两个数组的长度必须相等,否则不能接受为有效输入
是否有办法将DF中的Content
中的列标题转换为文本标签
预期输出:
>>Content A B C D E Labels
0 zxy 1 2 1 A, B, D
1 wvu 1 2 1 A, C, D
2 tsr 1 2 2 A, B, E
3 qpo 1 1 1 B, C, D
4 nml 2 2 C, D
5 kji 1 1 2 A, C, E
6 hgf 1 2 C, E
7 edc 1 2 1 A, B, D
完整解决方案:
#首先:清除字符前后的所有空白,所有列都可以
对于df.列中的列:
df[col]=df[col].str.strip()
#用0填充na
df.fillna(0,原地=真)
#将“”替换为0
df.replace(“”,0,原地=真)
#转换为int时,只能对包含数字数据的特定列执行此操作
#此列表是您显示的列名,如果它们在实际数据中不同,
#替换它们
对于['A','B','C','D','E']中的列:
df=df.astype({col:'int16'})
打印(df.info())
#你应该以这样的方式结束。
"""
范围索引:8个条目,0到7
数据列(共6列):
内容8非空对象
一个8非空的int16
B 8非空int16
c8非空int16
D 8非空int16
E 8非空int16
数据类型:int16(5),对象(1)
内存使用:272.0+字节
"""
我们可以这样做,注意这里,我将空格视为np.nan
,如果您的数据中真的是空白,请更改最后一行
#确保标签名称与相应的列匹配
s=df.loc[:,['A','B','C','D','E']]
#或
s=df.loc[:,'A':]
df['Labels']=(s>0).dot(s.columns+,').str[:-1]#列A:E需要是数字,而不是str
#df['Labels']=(~s.isin(['']).dot(s.columns+,').str[:-1]
这里有另一种使用np的方法。其中和groupby
:
r, c = np.where(df>0)
df['Labels'] = pd.Series(df.columns[c], index=df.index[r]).groupby(level=[0, 1]).agg(', '.join)
输出:
A B C D E Labels
0 zxy 1 2 0 1 0 A, B, D
1 wvu 1 0 2 1 0 A, C, D
2 tsr 1 2 0 0 2 A, B, E
3 qpo 0 1 1 1 0 B, C, D
4 nml 0 0 2 2 0 C, D
5 kji 1 0 1 0 2 A, C, E
6 hgf 0 0 1 0 2 C, E
7 edc 1 2 0 1 0 A, B, D
您也可以按如下方式执行此操作:
# melt the two dimensional representation to
# a more or less onedimensional representation
df_flat= df.melt(id_vars=['Content'])
# filter out all rows which belong to empty cells
# the following is a fail-safe method, that should
# work for all datatypes you might encouter in your
# columns
df_flat= df_flat[~df_flat['value'].isna() & df_flat['value'] != 0]
df_flat= df_flat[~df_flat['value'].astype('str').str.strip().isin(['', 'nan'])]
# join the variables used per original row
df_flat.groupby(['Content']).agg({'variable': lambda ser: ', '.join(ser)})
输出如下所示:
variable
idx Content
0 zxy A, B, D
1 wvu A, C, D
2 tsr A, B, E
3 qpo B, C, D
4 nml C, D
5 kji A, C, E
6 hgf C, E
7 edc A, B, D
给定以下输入数据:
import pandas as pd
import io
raw="""idx Content A B C D E
0 zxy 1 2 1
1 wvu 1 2 1
2 tsr 1 2 2
3 qpo 1 1 1
4 nml 2 2
5 kji 1 1 2
6 hgf 1 2
7 edc 1 2 1 """
df= pd.read_fwf(io.StringIO(raw))
df.drop(['idx'], axis='columns', inplace=True)
编辑:我刚在阅读后删除了'idx'
,创建了一个与原始数据帧类似的结构,并添加了一些可用于不同数据类型的故障保护代码(melt方法下面的两行)。如果更多地了解缺失值的实际表示方式,则可以简化代码。我得到类型错误:'>'在代码的第一行的'str'和'int
实例之间不受支持。请移动索引中数据帧的所有字符串列。我没有名为idx
的列,它只是默认数字我尝试在代码中删除此命令并使用它,但输出显示了您所编写的变量列中所有列标题的列表,而不仅仅是适用的标题ones@mvx,idx可能是原始数据帧的索引,它位于您提供的输出中。如果您没有将其作为列,只需从melt
和groupby
中删除“idx”,它将以同样的方式工作。顺便说一句,我根据您问题中的数据构建了数据框,即“给定以下输入数据”部分。我相信提出答案的ather preople也会这样做,但他们没有添加代码来获取答案中显示的输出的测试数据。但是,如果让它在数据帧上运行,我相信它会起作用,如果您的数据帧没有根本的不同,但在这种情况下,也许最好更改y中的描述我们的问题。如果它用代码显示所有列标题,那么空单元格似乎被转换为空字符串,而不是NaN
。在这种情况下,您只需更改行df_flat=df_flat[~df_flat['value']]。isna()
就像上面的编辑一样。我得到了AttributeError:'Series'对象没有属性'strip'
。使用df.astype
将A:E转换为intI,并将其包含在答案中。或者,df=df.astype({'A':'int16','B':'int16','C':'int16','D':'int16','E':'int16'))
尝试将numpy导入为np
如果没有导入numpy,则df.fillna(np.nan,inplace=True)
,然后再次尝试使用astype
。此外,不要尝试转换实际字符串(例如字母)toint
@jottbe我实际上正在与OP对话,试图解决他的问题,因为这些解决方案都不起作用。@mvx我真的不知道还有什么可以尝试。我们所做的一切都在玩具数据集上起作用,但不是真正的数据集。在这一点上,我不知道在看不到真实数据的情况下还可以尝试什么,因为这是一个问题真正的问题在哪里。你有链接或git repo吗?我可以在那里看到实际的数据?似乎空白点是空格'
。我可以从屏幕截图中看到,数据与玩具数据不同。假设只有内容
列有实际的文本,而其他列只有空白或空白数字。看起来很多列都有文本,这可以解释为什么什么都不起作用。是的,例如s=df.loc[:,'A':]
: