橙色 - 通过基于列值创建新行来重写数据

Orange - rewriting data by making new rows based on column values

我正在尝试处理 covid-19 病例数据

(来源,兴趣:https://github.com/CSSEGISandData/COVID-19/blob/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv

数据形成一个矩阵,在列中列出日期,在行中列出国家/地区。简化视图:

country 1/20/20 1/21/20 1/22/20 ... etc. ...
China   100     120     144     ... etc. ...
US      0       0       1       ... etc. ...
...
etc.
...

我正在尝试将日期列和数字转换为两个新功能,例如 "date" 和 "confirmed",例如:

country date     confirmed
China   1/20/20  100
China   1/21/20  120
China   1/22/20  144
US      1/20/20  0
US      1/21/20  0
US      1/22/20  1
...  etc.  ...

我对嵌入 Orange 的任何解决方案都感兴趣,当然 - 我们可以在导入数据之前准备数据!

您是尝试在脚本中还是使用 canvas 来完成?使用(纯)canvas,我猜你不能。您当然可以始终使用 Python 脚本小部件并在那里执行。

在脚本中(独立的或在 canvas 中)你应该将 Orange.data.Table 视为 immutable,尽管 Orange 本身并未强制执行。一些版本支持可以更改行数的过时方法已被删除。您仍然可以就地更改数据,但我不推荐这样做。

您必须创建一个新的 table,它从一开始就具有合适的大小。我想最简单的方法是在 Python 列表(列表)中收集您需要的所有数据,然后将其传递给 Table.from_list.

披露:我是 Orange 开发人员之一,我正在使用这些数据撰写博客 post。这将是一个系列,我们还会在一两周内展示一些这样的脚本。

Janez 的回答正是我需要的信息,谢谢。

这里我post橙色的python脚本代码,给出问题的完整解决方案。

from Orange.data import Domain, TimeVariable, ContinuousVariable, StringVariable, Table

# toISODate: parse the date string and returns it in ISO format
def toISODate(s):
    bits = s.split('/')
    year = '20'+bits[2];
    day = bits[1]
    day = day if len(day)==2 else '0'+day
    month = bits[0]
    month = month if len(month)==2 else '0'+month
    return year+'-'+month+'-'+day

# Prepare output domain
tmVar = TimeVariable.make("Date");

out_domain = Domain([ContinuousVariable.make("Lat"),
                     ContinuousVariable.make("Long"),
                     tmVar,
                     ContinuousVariable.make("Count")],
                    [],
                    [StringVariable.make("Country"),
                     StringVariable.make("Region")]
                   )

# Prepare output source - list of lists
out_source = []

in_domain = in_data.domain # not really needed
in_width = len(in_domain) # oops - thank you @community for the reminder

# outer loop through original data rows
for in_row in in_data:
   lat, long = in_row[0], in_row[1] # grab latitute, longitude
   country, region = in_row.metas[1], in_row.metas[0]
   # inner loop through dates in each row
   for j in range(2,in_width):
      date = tmVar.parse(toISODate(in_domain[j].name)) # find date (in clolumn names), parse to UNIX
      # make new row: lat, long, date, number of cases, country, region
      out_row = [lat, long, date, in_row[j], country, region]
      out_source.append(out_row)
   # end
# end in_row

# Make data from the list
out_data = Table.from_list(out_domain,out_source)

理想情况下,应该编写代码来处理任何矩阵(将 x 列、y 行、值转换为包含 x、y、值三列的高 table;然后处理补充列) .我的 Python 还没有达到要求。

此外,可以将内循环中的'in_width'值替换为'in_data.domain.attributes'。这样做将确保循环将覆盖不断增加的 nb 列(每天一个新的)