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:用增加的计数器填充的主要内容,如果未能解决你的问题,请参考以下文章