【问题标题】:Looping through file with .ix and .isin使用 .ix 和 .isin 循环文件
【发布时间】:2016-08-02 06:41:06
【问题描述】:

我的原始数据如下所示:

SUBBASIN HRU HRU_SLP    OV_N
1         1 0.016155144 0.15
1         2 0.015563287 0.14
2         1 0.010589782 0.15
2         2 0.011574839 0.14
3         1 0.013865396 0.15
3         2 0.01744597  0.15
3         3 0.018983217 0.14
3         4 0.013890315 0.05
3         5 0.011792533 0.05

我需要修改每个 SUBBASIN 编号的 OV_N 值:

hru = pd.read_csv('hru.csv')
for i in hru.OV_N:
    hru.ix[hru.SUBBASIN.isin([76,65,64,72,81,84,60,46,37,1,2]), 'OV_N'] = i*(1+df21.value[12])
    hru.ix[hru.SUBBASIN.isin([80,74,75,66,55,53,57,63,61,41,38,27,26,45,40,34,35,31,33,21,20,17,18,19,23,14,13,8,7,11,6,4,3,5,12]), 'OV_N'] = i*(1+df23.value[12])
    hru.ix[hru.SUBBASIN.isin([85,58,78,54,59,51,52,30,28,16,15,77,79,71,70,86,73,68,69,56,67,62,82,87,83,91,89,90,43,36,39,47,32,49,42,48,50,49,29,22,24,25,9,10]), 'OV_N'] = i*(1+df56.value[12])
    hru.ix[hru.SUBBASIN.isin([92,88,95,94,93]), 'OV_N'] = i*(1+df58.value[12])

其中 df21.value[12] 是 txt 文件中的值 该代码导致所有子流域的 OV_N 值无限大,因此我假设循环通过文件多次,但我找不到错误,并且此代码之前使用不同数量的子流域工作。

【问题讨论】:

    标签: python-2.7 loops pandas


    【解决方案1】:

    通常最好不要对 pandas DataFrame 中的行进行循环和索引。通过列操作转换 DataFrame 是更熊猫的方法。 pandas DataFrame 可以被认为是 pandas Series 的压缩组合:每一列都是它自己的 pandas Series ——所有列都共享相同的索引。可以将操作应用于一个或多个 pandas Series 以创建共享相同索引的新 Series。也可以应用操作将 Series 与一维 numpy 数组组合以创建新的 Series。了解pandas indexing 会很有帮助——但是这个答案只会使用顺序整数索引。

    修改每个 SUBBASIN 编号的 OV_N 值:
    通过从 hru.csv 中读取它来初始化 hru DataFrame,就像在原始问题中一样。这里我们使用问题中给出的数据对其进行初始化。

    import numpy as np
    import pandas as pd
    
    hru = pd.DataFrame({
        'SUBBASIN':[1,1,2,2,3,3,3,3,3],
        'HRU':[1,2,1,2,1,2,3,4,5],
        'HRU_SLP':[0.016155144,0.015563287,0.010589782,0.011574839,0.013865396,0.01744597,0.018983217,0.013890315,0.011792533],
        'OV_N':[0.15,0.14,0.15,0.14,0.15,0.15,0.14,0.05,0.05]})
    

    创建一个单独的 pandas Series,将来自各种 DataFrame(即 df21、df23、df56 和 df58)的所有值收集并存储到一个位置。这将用于按索引查找值。我们称之为 subbasin_multiplier_ds。让我们分别假设从 txt 文件中读取 21、23、56 和 58 的值。请将这些替换为从 txt 文件中读取的实际值。

    subbasin_multiplier_ds=pd.Series([21]*96)
    subbasin_multiplier_ds[80,74,75,66,55,53,57,63,61,41,38,27,26,45,40,
        34,35,31,33,21,20,17,18,19,23,14,13,8,7,11,6,4,3,5,12] = 23
    subbasin_multiplier_ds[85,58,78,54,59,51,52,30,28,16,15,77,79,71,70,
        86,73,68,69,56,67,62,82,87,83,91,89,90,43,36,39,47,32,49,42,48,50,
        49,29,22,24,25,9,10] = 56
    subbasin_multiplier_ds[92,88,95,94,93] = 58
    

    根据 DataFrame 中的列替换 hru DataFrame 中的 OV_N 并按索引在 subbasin_multiplier_ds 中查找。

    hru['OV_N'] =  hru['OV_N'] * (1 + subbasin_multiplier_ds[hru['SUBBASIN']].values)
    

    上面的 .values 创建了一个 numpy 数组,因此可以达到预期的结果。如果您想尝试删除值,请尝试看看会发生什么。

    【讨论】:

    • 感谢 SpeedCoder5 的回答。我只需要澄清一件事。在行中:subbasin_multiplier_ds=pd.Series([21]*96),我到底应该在括号中放什么?据我了解,您的意思是我需要将我的值乘以每个子流域编号?
    • [21]*96 不是乘法——而是一种 Python 方式,用于声明一个列表 96 项全部初始化为 21。subbasin_multipiler_ds 值每个都包含来自 txt 文件的 value[12] 中的任何内容对于每个数据框 df21、df23 等。原始问题在 .isin 检查中有 96 个项目。但是,如果有无限数量的算法,则可能需要查找而不是 Series。如果答案回答了问题,请务必将其标记为是。
    猜你喜欢
    • 1970-01-01
    • 2014-08-26
    • 2020-07-13
    • 1970-01-01
    • 2023-03-09
    • 2020-07-12
    • 2011-03-22
    • 2018-09-13
    • 1970-01-01
    相关资源
    最近更新 更多