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 以下的值,这只是由于我拥有的数据类型。
我有一个用 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 以下的值,这只是由于我拥有的数据类型。