OpenRefine:用增加的计数器填充

Posted

技术标签:

【中文标题】OpenRefine:用增加的计数器填充【英文标题】:OpenRefine: Fill down with increasing counter 【发布时间】:2017-11-17 10:24:24 【问题描述】:

是否可以在 OpenRefine 中使用计数器填充空白单元格而不是复制顶部的非空白值?

在此示例图像中:

或者这里是与输入文本相同的示例 - 将其图像为从上到下的一列:

1
1
blank
1
blank
blank
blank
blank
blank
1

我希望看到列填充如下(再次,想象一下从上到下):

1
1
2
1
2
3
4
5
6
1

谢谢,非常感谢您的帮助。

【问题讨论】:

【参考方案1】:

这并不简单。你必须:

1 将空格替换为其他内容,例如“x”

2 为整个数据集创建唯一记录

3 使用此 Jython 脚本:

import itertools
data = row['record']['cells']['YOUR COLUMN NAME']['value']
x = itertools.count(2)

liste = []
for i, el in enumerate(data):
    if data[i] == "x":
        liste.append(x.next())
    else:
        x = itertools.count(2)
        liste.append(el)

return ",".join([str(x) for x in liste])

4 使用 Blank down 清除重复项

5 拆分第一个多值单元格。

这是上述操作的截屏视频。

如果你懂一点 Python,你也可以使用 pandas 转换你的文件。我不知道最优雅的方法是什么,但是这个脚本应该可以工作。

import itertools
import pandas as pd

x = itertools.count(2)

def set_x():
    global x
    x = itertools.count(2)

set_x()

def increase(value):

    if not value:
        return next(x)
    else:
        set_x()
        return value

data = pd.read_csv("your_file.csv", na_values=['nan'], keep_default_na=False)


data['column 1'] = data['column 1'].apply(lambda row: increase(row))

print(data)

data.to_csv("final_file.csv")

【讨论】:

谢谢。上面的 OpenRefine 选项似乎并不完全符合我的要求。据我所知,它填充的值不是增加的计数器。例如,如果我有 5 个空白单元格,我希望它们填充 2、3、4、5、6 而不是 1、2、3、1、2。我可能会按照你的建议用 Python 或 R 来做。谢谢。 @EduardGeist 这正是它所做的:第一个单元格 x 被替换为 2,第二个单元格被替换为 3,依此类推。每次出现 1 时,计数器都会重置为 2,与您的示例完全相同。 对不起,是的!感谢您解决这个问题。 不客气。如果它有效并且没有提供更好的解决方案,请随时接受答案。 很好的答案,埃托雷!使用未发布的 OpenRefine 版本(在 3.4.1 上尚不可用)会有更简单的方法。您将能够使用cross() 获取上一行,那么这将只是if previousRow = 1 return 2 else return previousRow + 1 (伪代码)的问题。见github.com/OpenRefine/OpenRefine/issues/…【参考方案2】:

这里有两个使用 GREL 的简单解决方案。

使用记录

您可以将列移到开头,告诉 OpenRefine 使用数字作为记录。您可能需要将列转换为文本才能真正说服 OpenRefine 将其用作记录。 然后添加新列或使用以下表达式转换现有列。

1 + row.index - row.record.fromRowIndex

使用记录标记

如果您不想使用记录或没有静态编号,您可以创建类似的设置。想象一下,您有一个如下表所示的不完整计数器并想要填充它。

Origin Desired
1 1
2
1 1
2 2
3
1 1

要填充缺失的单元格,首先使用以下表达式基于您的原始列添加一个新列,并将其命名为 record_row_index

if(isNonBlank(value), row.index, "")

之后fill down 原始列和新列record_row_index

然后使用以下表达式在原始填充列的基础上创建一个新列。

value + row.index - cells["record_row_index"].value

提示:表达式要求两列都是数字类型。 如果其中一个是文本类型,您可以预先转换列或在表达式中使用toNumber()。

下表显示了这些操作如何协同工作。

Origin Origin filled row.index record_row_index Desired
1 1 0 0 1 + 0 - 0 = 1
1 1 0 1 + 1 - 0 = 2
1 1 2 2 1 + 2 - 2 = 1
2 2 3 3 2 + 3 - 3 = 2
2 4 3 2 + 4 - 3 = 3
1 1 5 5 1 + 5 - 5 = 1

【讨论】:

以上是关于OpenRefine:用增加的计数器填充的主要内容,如果未能解决你的问题,请参考以下文章

根据一维计数器数组填充二维数组列

Spring kafka记录标题未正确填充

SwiftUI 列表项增加计数

如何在正文视图中使用计数器来填充列表

需要同步增量计数器?

在后台运行计数器