Python 以迭代方式将第一列中的文本与其他列中的现有文本组合

Python 以迭代方式将第一列中的文本与其他列中的现有文本组合,python,pandas,merge,concatenation,Python,Pandas,Merge,Concatenation,我正在创建一个python脚本,该脚本从我们研究实验室内的一个设备上的一个设计糟糕的输出文件(我无法更改)中提取数据。我想提供一种方法,以迭代方式将数据帧第一列(下面的示例)中的文本与数据帧中的其他列相结合 数据帧的一个简单示例: 文件名 1. 2. 3. 4. 5. A. 第(1)页 第(2)页 第(3)页 第(4)页 .... B 第(1)页 第(2)页 -------- -------- .... C 第(1)页 第(2)页 第(3)页 第(4)页 .... D 第(1)页 第(2)页 第

我正在创建一个python脚本,该脚本从我们研究实验室内的一个设备上的一个设计糟糕的输出文件(我无法更改)中提取数据。我想提供一种方法,以迭代方式将数据帧第一列(下面的示例)中的文本与数据帧中的其他列相结合

数据帧的一个简单示例:

文件名 1. 2. 3. 4. 5. A. 第(1)页 第(2)页 第(3)页 第(4)页 .... B 第(1)页 第(2)页 -------- -------- .... C 第(1)页 第(2)页 第(3)页 第(4)页 .... D 第(1)页 第(2)页 第(3)页 -------- .... E 第(1)页 第(2)页 第(3)页 第(4)页 .... F 第(1)页 -------- -------- -------- .... 尝试:

  • 使用
    .apply
    'Filename'
    字符串前置到其他列
  • 在当前的答案中,来自的解决方案是最快的解决方案,针对一个包含100k行的3列数据帧进行测试
  • 如果您的数据帧包含不需要的字符串(例如,
    '----------'
    ),则在组合列字符串之前,请使用类似于
    df.replace('----------',pd.NA,inplace=True)
    • 如果最终结果必须有
      '----------'
      ,则在最后使用
      df.fillna('----------',inplace=True)
      。这比尝试迭代处理它们要好
将熊猫作为pd导入
将numpy作为np导入
#测试数据帧
df=pd.DataFrame({'Filename':['a','b','c'],'c1':['s1']*3,'c2':['s2',np.nan',s2']})
#显示(df)
文件名c1 c2
0 a s1 s2
1 b s1南
2 c s1 s2
#将文件名字符串前置到其他列
df.iloc[:,1::]=df.iloc[:,1:].apply(lambda x:df.Filename+'.'+x)
#显示(df)
文件名c1 c2
0 a a_s1 a_s2
1 b_s1南
2 c_s1 c_s2
%%timeit
对照其他答案进行测试
#具有100k行的测试数据
df=pd.concat([pd.DataFrame({'Filename':['a','b','c'],'c1':['s1']*3,'c2':['s2']*3})]*33333)。重置索引(drop=True)
#来自特伦顿的解决方案
%%时间
df.iloc[:,1::].apply(lambda x:df.Filename+'.'+x)
[out]:
每个回路33.6 ms±1.17 ms(7次运行的平均值±标准偏差,每个10个回路)
#来自Mykola的解决方案
%%时间
df['Filename'].to_numpy().重塑(-1,1)+'''.+df.loc[:,'c1':]
[out]:
每个回路29.6 ms±2.5 ms(7次运行的平均值±标准偏差,每个10个回路)
#亚历克斯的解决方案
%%时间
df.loc[:,cols].apply(lambda s:df[“Filename”].str.cat(s,sep=“”))
[out]:
每个回路45.3 ms±1.08 ms(7次运行的平均值±标准偏差,每个回路1次)
#迭代for循环中的列
def测试(d):
对于d列[1:]中的列:
d[cols]=d['Filename']+'.'+d[cols]
返回d
%%时间
测试(df)
[out]:
每个回路53.8 ms±4.75 ms(7次运行的平均值±标准偏差,每个10个回路)

我将
-----------
表示为
np.NaN
。当您看到
NaN\u值时,应该能够将它们标记为NaN

这是数据帧的dict:

d={
1:[nan,“第(1)页”,nan],
2:[nan,“第(2)页”,nan],
3:[“第(3)页”,nan,“第(3)页],
4:[“第(4)页”,楠,楠],
“文件名”:[“a”、“b”、“c”],
}
df=pd.DatFrame(d)
然后我们可以:

  • 为我们要更改的列制作一个掩码,除了
    文件名
cols=df.columns!=“文件名”
#数组([True,True,True,True,False])
  • 应用一个函数,该函数使用:
df.loc[:,cols]=df.loc[:,cols].apply(lambda s:df[“Filename”].str.cat(s,sep=“”))
此函数获取
cols
中指定的每一列,并将其与
Filename
列连接起来

产生:

1234文件名
0 NaN NaN a_表(3)a_表(4)a
1张单张(1)单张(2)单张(2)单张
2 NaN-NaN c_表(3)NaN c

例如,如果您有以下数据框:

  col1 col2 col3 col4
0    a    x    y    z
1    b    x    y    z
2    c    x    y  NaN
您可以使用:

结果:

  col1 col2 col3 col4
0    a  a_x  a_y  a_z
1    b  b_x  b_y  b_z
2    c  c_x  c_y  NaN

这会产生类型错误:无法使用类型为的索引器[1]对索引进行切片索引int@lake08您的列名类型是
int
还是
str
?可能是
str
。因此,您可以在
loc
中用“1”替换1,感谢您的快速回复,它们是str的。我尝试用loc中的“1”替换1,并抛出一个键错误:“1”。数据集中的实际“文件名”示例为“Highland Range_Site 5_2021-01-14_08-59-20.xlsx”,这很有帮助。这并不能回答问题。若要评论或要求作者澄清,请在其帖子下方留下评论。-@比延德拉:你为什么这么说?这似乎是我的答案。仅供参考:彻底回答问题很费时。如果你的问题得到了解决,那就接受最符合你需要的解决方案来表示感谢。这个✔ 位于答案左上角的上/下箭头下方。如果出现更好的解决方案,则可以接受新的解决方案。如果你有15+的声誉,你也可以用向上或向下箭头对答案的质量/帮助性进行投票。如果解决方案不能回答问题,请留下评论。非常感谢。
df.loc[:, 'col2':] = df['col1'].to_numpy().reshape(-1, 1) + '_' + df.loc[:, 'col2':]
  col1 col2 col3 col4
0    a  a_x  a_y  a_z
1    b  b_x  b_y  b_z
2    c  c_x  c_y  NaN