【问题标题】:pandas: how to select an all rows of a dataframe that meet a condition (ValueError: "Arrays were different lengths")pandas:如何选择满足条件的数据帧的所有行(ValueError:“数组长度不同”)
【发布时间】:2018-12-05 16:52:41
【问题描述】:

Python 2.7

我有一个包含两列的数据框,coordinatesloccoordinates 包含 10 个 lat/long 对,而 loc 包含 10 个字符串。

以下代码导致 ValueError,数组的长度不同。好像我写的条件不正确。

lst_10_cords = [['37.09024, -95.712891'], ['-37.605, 145.146'], ['43.0481962, -76.0488458'], ['29.7604267, -95.3698028'], ['47.6062095, -122.3320708'], ['34.0232431, -84.3615555'], ['31.9685988, -99.9018131'], ['37.226582, -95.70522299999999'], ['40.289918, -83.036372'], ['37.226582, -95.70522299999999']]
lst_10_locs = [['United States'], ['Doreen, Melbourne'], ['Upstate NY'], ['Houston, TX'], ['Seattle, WA'], ['Roswell, GA'], ['Texas'], ['null'], ['??, passing by...'], ['null']]
df = pd.DataFrame(columns=['coordinates', 'locs'])
df['coordinates'] = lst_10_cords
df['locs'] = lst_10_locs
print df
df = df[df['coordinates'] !=  ['37.226582', '-95.70522299999999']] #ValueError

错误信息是

文件“C:\Users...\Miniconda3\envs\py2.7\lib\site-packages\pandas\core\ops.py”,林 e 1283,在包装中 res = na_op(值,其他) 文件“C:\Users...\Miniconda3\envs\py2.7\lib\site-packages\pandas\core\ops.py”,林 e 1143,在 na_op 结果 = _comp_method_OBJECT_ARRAY(op, x, y) 文件“C:...\biney\Miniconda3\envs\py2.7\lib\site-packages\pandas\core\ops.py”,林 e 1120,在 _comp_method_OBJECT_ARRAY 结果 = libops.vec_compare(x, y, op) 文件“pandas/_libs/ops.pyx”,第 128 行,在 pandas._libs.ops.vec_compare ValueError:数组的长度不同:10 vs 2

我的目标是实际检查并消除坐标列中等于列表[37.226582, -95.70522299999999] 的所有条目,所以我希望df['coordinates'] 打印出[['37.09024, -95.712891'], ['-37.605, 145.146'], ['43.0481962, -76.0488458'], ['29.7604267, -95.3698028'], ['47.6062095, -122.3320708'], ['34.0232431, -84.3615555'], ['31.9685988, -99.9018131'], ['37.226582, -95.70522299999999'], ['40.289918, -83.036372']

我希望这份文档会有所帮助,尤其是显示的部分: “您可以使用与 DataFrame 的索引长度相同的布尔向量从 DataFrame 中选择行(例如,从 DataFrame 的列之一派生的东西):” df[df['A'] > 0]

所以看起来我的语法不太正确......但我被卡住了。如何编写为某列的单元格值设置条件并返回仅包含符合该条件的单元格的行的数据框?

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    好的,这是一种确保您有干净的数据可以操作的方法。

    让我们假设 4 个条目带有脏坐标条目。

    lst_4_cords = [['37.09024, -95.712891'], ['-37.605, 145.146'], ['43.0481962, -76.0488458'], ['null']]
    lst_4_locs = [['United States'], ['Doreen, Melbourne'], ['Upstate NY'], ['Houston, TX']]
    df = pd.DataFrame(columns=['coordinates', 'locs'])
    df['coordinates'] = lst_4_cords
    df['locs'] = lst_4_locs
    
    
        coordinates                     locs
    0   [37.09024, -95.712891]      [United States]
    1   [-37.605, 145.146]          [Doreen, Melbourne]
    2   [43.0481962, -76.0488458]   [Upstate NY]
    3   [null]                      [Houston, TX]
    

    现在我们制作一个清洁方法。您真的想使用以下方法测试值:

    type(value) is list.
    type(value[0]) is string.
    value[0].split(",") has two elements 
    each element can cast to float - etc. 
    Each is valid to be a lat or a lon
    

    但是,我们将使用 try except 以肮脏的方式进行操作。

    def scrubber_drainer(value):
        try:
            # we assume value is a list, with a single string in position zero, that string has a comma, that we can split into a tuple of two floats
            return tuple([float(value[0].split(",")[0]),float(value[0].split(",")[1])])
        except:
            # return tuple (38.9072,77.0396) # swamp
            return tuple([0.0,0.0]) # some default
    

    所以返回通常是一个带有 2 个浮点数的元组。如果它不能成为我们返回一个默认值 (0.,0.)。

    现在更新坐标

    df['coordinates'] = df['coordinates'].map(scrubber_drainer)
    

    然后我们使用这个很酷的technique 来拆分元组

    df[['lat', 'lon']] = df['coordinates'].apply(pd.Series)
    

    现在你可以使用 np.isclose() 来过滤

    【讨论】:

      【解决方案2】:

      你能考虑一下吗?:

      df
          coordinates                 locs
      0   [37.09024, -95.712891]      [United States]
      1   [-37.605, 145.146]          [Doreen, Melbourne]
      2   [43.0481962, -76.0488458]   [Upstate NY]
      3   [29.7604267, -95.3698028]   [Houston, TX]
      4   [47.6062095, -122.3320708]  [Seattle, WA]
      5   [34.0232431, -84.3615555]   [Roswell, GA]
      6   [31.9685988, -99.9018131]   [Texas]
      7   [37.226582, -95.705222999]  [null]
      8   [40.289918, -83.036372]     [??, passing by...]
      9   [37.226582, -95.7052229999] [null]
      
      
      df['lat'] = df['coordinates'].map(lambda x: np.float(x[0].split(",")[0]))
      df['lon'] = df['coordinates'].map(lambda x: np.float(x[0].split(",")[1]))
      df[~((np.isclose(df['lat'],37.226582)) & (np.isclose(df['lon'],-95.70522299999999)))]
      
      
          coordinates                 locs                 lat        lon
      0   [37.09024, -95.712891]      [United States]      37.090240  -95.712891
      1   [-37.605, 145.146]          [Doreen, Melbourne] -37.605000  145.146000
      2   [43.0481962, -76.0488458]   [Upstate NY]         43.048196  -76.048846
      3   [29.7604267, -95.3698028]   [Houston, TX]        29.760427  -95.369803
      4   [47.6062095, -122.3320708]  [Seattle, WA]        47.606209  -122.332071
      5   [34.0232431, -84.3615555]   [Roswell, GA]        34.023243  -84.361555
      6   [31.9685988, -99.9018131]   [Texas]              31.968599  -99.901813
      8   [40.289918, -83.036372]     [??, passing by...]  40.289918  -83.036372
      

      【讨论】:

      • 啊,这一天终于到来了……我现在正在查找它,但我不太了解 lambda 函数(也不是 map 函数)。你能试着用文字解释一下你在df['lat'] = ...线上做什么吗?实际上,在我的情况下,这似乎并不完全有效,因为 df['coordinates'] 中的某些条目只是表示“null”的字符串。所以如果你能在这里帮助解释一下可以帮助我修改代码的 lambda 函数
      • 看起来像 Series.apply(func_obj) 可以用来创建相对于 lambda 表达式更复杂的函数pandas.pydata.org/pandas-docs/stable/generated/…
      • 所以我使用了一个较小版本的原始数据集来回答这个问题。但似乎我在lst_of_10_coordinates 中有一些条目(好吧,当我抓取超过 10 个坐标时)只有 ["null"]。单个 lambda 表达式不起作用,遇到 ["null"] 列表时会出错。现在我只是......制作一个不太优雅的 for 循环,可以帮助我成功过滤行,但是如果您了解可以使这项任务更容易的其他 pandas 命令......(我应该提出一个单独的问题吗? )
      • 看看这里能不能搞定。我们需要一种清理方法来映射您的所有条目。让我们假设所有都是带有单个字符串条目的列表类型。我稍后回复
      【解决方案3】:

      如果您查看数据框存储坐标的对象,则会出现一个问题,因为您看到它是单个字符串。您遇到的错误问题似乎是将 10 个元素系列 .coordinates 与 2 个元素列表进行比较,显然存在不匹配。使用 .values 似乎可以解决这个问题。

      df2 = pd.DataFrame([row if row[0]!= ['37.226582, -95.70522299999999'] else [np.nan, np.nan] for row in df.values ], columns=['coords' , 'locs']).dropna()

      【讨论】:

        猜你喜欢
        • 2018-03-20
        • 2017-11-15
        • 2020-12-25
        • 2015-09-29
        • 2021-12-14
        • 1970-01-01
        • 1970-01-01
        • 2021-08-08
        • 1970-01-01
        相关资源
        最近更新 更多