我有一个包含9列的数据集,我设法使用pandas提取了两个列(感谢Stack成员之前的帮助!)。现在,我的问题是:我有一个值列表,用于从数据集中提取并提取相应的值。提取的数据集如下所示:
Exp. m/z Intensity
1000 2000
2000 3000
3000 4000
4000 5000
等等(每个数据集大约有500多行)。用于取件的清单如下:
mass
1200
1300
等等(拾取列表约200行)。每个质量值将用于计算上部和下部垃圾箱,它们将用于拾取Exp。来自数据集的m / z值。因此,例如,质量1200将被计算为1250(上部)和1150(下部),并且将从数据集中获取该范围内的任何内容,并且其相应的强度值是我想要的。如果没有拾取,我希望结果为空值,因为我认为0值会影响平均值和其他统计分析。
下面是我的代码,其中file是数据集,pickfile是拾取列表:
从pandas导入DataFrame
import pandas as pd
import numpy as np
file = 'C09.xls'
pickupfile = 'pickuplist.xlsx'
xl = pd.ExcelFile(file)
pl = pd.ExcelFile(pickupfile)
plist = pd.read_excel(xl)
pickuplist = pd.read_excel(pl)
cmass = plist['Exp. m/z']
height = plist['Intensity']
plistcollect = pd.concat([cmass, height], axis=1)
ppm = 150
peak1upper = round(pickuplist*(1+ppm/1000000),4)
peak1lower = round(pickuplist*(1-ppm/1000000),4)
pickup = plistcollect[((plistcollect['Exp. m/z']>peak1lower) & (plistcollect['Exp. m/z'] < peak1upper))]
print(pickup['Intensity'])
当我执行此代码时,我收到一条错误消息:ValueError:条件所需的布尔数组,而不是float64。我明白我的数据集是浮动值,所以你们有一些提示或提示/建议吗?
非常感谢!!
编辑: 忘记提到我的数据和两个限制(peak1lower&amp; peak1upper)是float64类型。
我也试过像isin那样的拾音器:
pickup = plistcollect[plistcollect.isin(np.arange(peak1lower,peak1upper))]
答案 0 :(得分:1)
如果索引数据框时有多个条件,则所有条件都在另一个括号内。
plistcollect[(plistcollect['Exp. m/z']>peak1lower) & (plistcollect['Exp. m/z'] < peak1upper)]
应该是
plistcollect[((plistcollect['Exp. m/z']>peak1lower) & (plistcollect['Exp. m/z'] < peak1upper))]
编辑:由于您需要在每个元素上执行它,您必须执行以下操作:
limit_df = pd.DataFrame([peak1lower['Exp. m/z'],peak1upper['Exp. m/z']], index=['lower','upper']).T
filtered_df = limit_df.apply(lambda x: ((plistcollect['Exp. m/z'] > x.lower) & (plistcollect['Exp. m/z'] < x.upper)), axis=1)
filtered_df会给你一个布尔数据框架,每一行都有True,False对应于属于质量列表给定元素的DataFrame条目。
更简单的方法是单独保存文件:
def filter_df(x):
plistcollect[((plistcollect['Exp. m/z'] > x.lower) & (plistcollect['Exp. m/z'] < x.upper))].to_csv("test_%s.csv"%x.name)
limit_df.apply(lambda x: filter_df(x), axis=1)
答案 1 :(得分:1)
一种解决方案是创建一个新的DataFrame,将来自pickuplist的值作为索引,并从plist作为列
matches = pd.DataFrame(index=pickup['mass'], columns = plist.set_index(list(plist.columns)).index, dtype=bool)
然后根据需要填充此DataFrame,例如,您可以只使用目标150ppm而不是使用abs
进行此双边比较
ppm = 150
for index, exp_mass, intensity in plist.itertuples():
matches[exp_mass] = abs(matches.index - exp_mass) / matches.index < ppm / 1e6
这就是这样的
Exp. m/z 1000 2000 3000 4000
Intensity 2000 3000 4000 5000
mass
1000 True False False False
1200 False False False False
1300 False False False False
你可以轻松地用词汇理解来压缩
results = {i: list(s.index[s]) for i, s in matches.iterrows()}
返回pickuplist
中plist
中每一行的每一行的dict条目,以(Exp. m/z, Intensity)
形式出现{1000: [(1000, 2000)], 1200: [], 1300: []}
(Exp. m/z, Intensity)
如果您只想要results2 = {key for key, value in matches.any().iteritems() if value}
元组,则可以执行此操作
set
这给了{(1000, 2000)}
$ jq -c '.[] | map_values(.[1:]) | .k1,.k2' <<< "$json" | paste -d "," - -
"http://url",null