Pandas - 从 Pandas 中的同一个字符串中选择几个浮点数来操作它们

Pandas - Choose several floats from the same string in Pandas to operate with them

我有一个用 Pandas 提取的数据框,其中一个列看起来像这样:

我想做的是提取此列中的数值(浮点数),我自己可以做到。问题来了,因为我有一些单元格,比如图像中的单元格 20,其中我有多个数字,所以我想对这些值取平均值。我认为为此,我首先需要识别字符串中不同的数值组(每个浮点数),然后将它们提取为浮点数,然后对它们进行操作。我不知道该怎么做。

Edit:我已经使用正则表达式中的 re.findall 命令找到了解决方案。这是基于此线程 .

中的一个问题的回答
for index,value in z.iteritems():
z[index]=statistics.mean([float(h) for h in re.findall(r'(?:\b\d{1,2}\b(?:\.\d*))',value)])

请注意,由于我拥有的数据类型,我没有包括对整数的匹配,并且只考虑了最大 99 的值。

但是,由于循环,我在使用这种方法时收到警告(当我只对系列中的一个元素执行此操作时没有警告):

SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame

虽然我没有发现我的数据有任何问题,但这个警告重要吗?

我认为您可以从此处的 Pandas 矢量化操作中获益。在原始数据帧上使用 findall 并按顺序应用 pd.Series 从列表转换为列和 pd.to_numeric 从字符串转换为数字类型(默认 return dtype 是 float64).然后用 .mean(axis=1).

计算每行值的平均值
import pandas as pd

d = {0: {0: '2.469 (VLT: emission host)',
  1: '1.942 (VLT: absorption)',
  2: '1.1715 (VLT: absorption)',
  3: '0.42 (NOT: absorption)|0.4245 (GTC)|0.4250 (ESO-VLT UT2: absorption & emission)',
  4: '3.3765 (VLT: absorption)',
  5: '1.86 (Xinglong: absorption)| 1.86 (GMG: absorption)|1.859 (VLT: absorption)',
  6: '<2.4 (NOT: inferred)'}}

df = pd.DataFrame(d)
print(df)

s_mean = df[0].str.findall(r'(?:\b\d{1,2}\b(?:\.\d*))')\
        .apply(pd.Series)\
        .apply(pd.to_numeric)\
        .mean(axis=1)

print(s_mean)

来自 s_mean

的输出
0    2.469000
1    1.942000
2    1.171500
3    0.423167
4    3.376500
5    1.859667
6    2.400000

根据我之前在原post的编辑中写的内容找到了解决方案:

它包括将 re.findall() 命令与 正则表达式 一起使用,如 post 在此线程 中编辑:

statistics.mean([float(h) for h in re.findall(r'(?:\b\d{1,2}\b(?:\.\d*))',string)])

然后,要在数据框列上循环,只需使用lambda x:方法和pandas应用命令(df.apply)。为此,我定义了一个执行上述操作的函数(redshift_to_num),然后将此函数应用于数据框列中的每个元素:

import re
import pandas as pd
import statistics

def redshift_to_num(string):
    measures=[float(h) for h in re.findall(r'(?:\b\d{1,2}\b(?:\.\d*))',string)]
    mean=statistics.mean(measures)
    return mean

df.Redshift=df.Redshift.apply(lambda x: redshift_to_num(x))

备注:

  • 我的案例中感兴趣的数据存储在数据框列 df.Redshift
  • re.findall 命令中,我没有包括整数匹配,并且只考虑了 99 以下的值,这只是由于我拥有的数据类型。