在从csv文件

时间:2017-06-29 18:01:06

标签: function csv netlogo agent-based-modeling

我的问题有点长。我真的很感激,如果你能够阅读这一切,我会非常感谢任何建议。

我有2位消费者的数据是作为评价过笔记本电脑的海龟。特征。笔记本电脑有两种功能:屏幕尺寸和电池寿命。每个都有一些水平。例如,电池寿命为5小时,12小时,24小时,30小时。数据存储在csv文件中。

   12 13.5 14 15 5 12 24 30
1  1   2    1  3 2  2  4  5
2  4   3    1  2  1 1  2  3

我想总结两个级别的功能。例如,对于消费者1和2,则是:

屏幕尺寸的总和率为13.5 +电池寿命率24

由于13.5和24可能会稍后改变,我想知道例如14的大小和电池寿命为5的速率之和,我使用" to-reports"定义了两个函数。 。此外,例如,值" 12"在标题行中两次表示大小和电池寿命,我制作了2个csv文件子集,一个用于屏幕大小,另一个用于电池。

   12 13.5 14 15 
1  1   2    1  3 
2  4   3    1  2  

   5 12 24 30
1  2  2  4  5
2  1 1  2  3

首先在主程序中读取csv文件,并为每一行分配一只乌龟,期望有两个消费者。

to setup
  ca
  reset-ticks
  file-close-all
  file-open "turtle_details.csv"
 let headerrow csv:from-row file-read-line
 set Sc 13.5   ; at the beginning I want the rate of this screen size
 set Bat 24
   while [ not file-at-end? ] [
    let data csv:from-row file-read-line
      create-consumers 1 [
         set shape "person"
         set k k + 1
       print  obtain-Sc (Sc) + obtain-Bat (Bat)
      ]
   ]
  file-close-all
end

我假设,首先,读取第一行并生成消费者。现在它去报告找到获取屏幕(13.5),这是2,但我想下次调用obrain_Screen,再次csv打开,光标仍然在开头,但我想让它读取第二排。为了扩展它,我可能需要它进一步发展。为了解决这个问题,我定义了一个计数器k,例如第一次检查这个条件:idx = 0< k = 1,因此读取第一行。然后idx = idx + 1,所以没有别的事。

to-report obtain-Screen[Sc]
  file-close-all ; close all open files

  file-open  "turtle_detailsSc.csv" 
  let headings csv:from-row file-read-line
  ifelse  is-number? position Sc headings
    [
      while [idx < k ]
      [ set fdata csv:from-row file-read-line
        set idx idx + 1
      ]
      report item position Sc headings fdata
]
[report 0.000000009]

蝙蝠类似的东西。但它不起作用并且有错误。任何想法如何改进报告? 谢谢

修改

考虑到数据集如下:

   size12  size13.5  size14  size15  Battery5  Battery12 Battery24 Battery30 
1  1        *2*         1      3        2         2           *4*       5
2  4        3           3      2        1          1           2        3

我现在可以访问数据集,并且每个消费者都可以找到他们对购买的笔记本电脑的评价。例如,消费者1的笔记本电脑尺寸为13.5,电池寿命为24。

Consumer 1 evaluation of size 13.5 = 2
Consumer 1 evaluation of battery 24 = 4
Overall evaluation of laptop = 2 + 4 = 6

我已经定义了一个程序&#34; Find Eval&#34;当我需要知道不同消费者的评价时,它使我能够访问数据集并找到值。

为了更多地解释表格中的数据,消费者有一台笔记本电脑,所以可以很好地评估它,但对于其他功能,例如他如何评估屏幕尺寸为15的笔记本电脑,他可能有一些曝光或只是通过听证会来自其他人,他已填写表。

我希望保留这两位消费者并监控他们在20年内对笔记本电脑功能的态度。在第2年,消费者1可能更新了他的系统,所以现在他的电池寿命是30.这次我需要做的是访问数据集并计算

Consumer 1 evaluation of size 13.5 = 2

Consumer 1 evaluation of battery 30 = 5



  Overall evaluation of laptop = 2 + 5 = 7

这一次,我需要去找电池30的值。 我想当我重复我的代码20年时,每次我想要使用数据集时都会重复创建 - 消费者,因此每年不会保留2个消费者,而是创建一些新的消费者,之前的消费者将是完全取代了。

问题是我如何创建一次消费者,但可以多次访问数据集中的任何数据点?

非常感谢,

1 个答案:

答案 0 :(得分:3)

回应你的评论 - 得到它,认为可能是这种情况。我将提出一种可能适合或不适合您的替代方法,但我可能会解决这个问题。主要区别在于我将屏幕和电池额定值列表存储在一个乌龟变量中,因此您可以在事后轻松访问它们而无需跟踪计数器。鉴于这些变量声明:

extensions [ csv ]

globals [ screen-headings battery-headings]

turtles-own [ 
  turtle-screen-list 
  turtle-battery-list
  turtle-screen-eval
  turtle-bat-eval
  turtle-sum-eval
  turtle-row-number
]

我会将csv文件的标题拆分为screen-headingsbattery-headings全局变量。

然后,我将迭代csv的下一行,如下所示,并以类似的方式将行拆分为turtles-own变量turtle-screen-listturtle-battery-list。这样,每只乌龟都知道自己对每个屏幕和电池的评级,因此您可以根据需要修改评估的屏幕或电池。

使用screen-to-evaluatebattery-to-evaluate设置感兴趣的屏幕和电池(或在界面上使用Chooser),然后使用记者(类似于您设置的那个)检查电池和感兴趣的屏幕的位置以返回当前海龟的评级 - 这将设置turtle-screen-evalturtle-bat-eval。最后,将最后两个值相加。

to setup
  ca
  reset-ticks
  file-close-all
  file-open "turtle_details.csv"
  let headings csv:from-row file-read-line
  set screen-headings sublist headings 0 4
  set battery-headings sublist headings 4 length headings

  let screen-to-evaluate 13.5
  let battery-to-evaluate 24

  while [ not file-at-end? ] [
    let data csv:from-row file-read-line
    create-turtles 1 [
      set turtle-screen-list sublist data 0 4
      set turtle-battery-list sublist data 4 length data
      set turtle-screen-eval turtle-screen-rating screen-to-evaluate
      set turtle-bat-eval turtle-battery-rating battery-to-evaluate
      set turtle-sum-eval turtle-screen-eval + turtle-bat-eval
    ]
  ]
  file-close-all

end

to-report turtle-screen-rating [sc]
  let pos position sc screen-headings
  let turt-screen-rate-value item pos turtle-screen-list
  report turt-screen-rate-value
end

to-report turtle-battery-rating [bc]
  let pos position bc battery-headings
  let turt-bat-rate-value item pos turtle-battery-list
  report turt-bat-rate-value
end

当然,你可以根据需要浓缩一些。我测试了这个设置有4行(在您的示例数据后图案化),它似乎工作正常。如果你有大量的行,它可能无法正常工作。

修改

如果您最终使用界面选择器替换screen-to-evaluatebattery-to-evaluate(我建议 - 它可以让您快速查看不同的值),您可以使用以下内容更新为新值: / p>

to update-vals
  ask turtles [
    set turtle-screen-eval turtle-screen-rating scrn
    set turtle-bat-eval turtle-battery-rating batr
    set turtle-sum-eval turtle-screen-eval + turtle-bat-eval
  ]
end

其中scrnbatr是选择者的名称。

或者,如果您希望它们动态更新,您可以创建一个报告以下记者的界面监视器:

to-report update
ask turtles [
    set turtle-screen-eval turtle-screen-rating scrn
    set turtle-bat-eval turtle-battery-rating batr
    set turtle-sum-eval turtle-screen-eval + turtle-bat-eval
  ]
  report "Dynamically updating."
end

有了这个,只要你更改Chooser值,海龟就应该立即更新他们的turtle-bat-evalturtle-screen-evalturtle-sum-eval。有趣!

修改2

如果您的csv包含行号的列,请执行以下操作:

row 12 13.5 14 15  5 12 24 30
1   1  2.0  1  3  2  2  4  5
2   4  3.0  1  2  1  1  2  3

我建议创建一个turtle变量来存储使用的行号。我现在包括一个名为turtle-row-number的人。然后,您只需要包含一行来更新列表中first项的变量,即行号,然后相应地修改sublist值,如下所示:

to setup-row-nums
  ca
  reset-ticks
  file-close-all
  file-open "turtle_details_2.csv"
  let headings csv:from-row file-read-line
  set screen-headings sublist headings 1 5
  set battery-headings sublist headings 5 length headings

  while [ not file-at-end? ] [
    let data csv:from-row file-read-line
    create-turtles 1 [
      set turtle-row-number first data 
      set turtle-screen-list sublist data 1 5
      set turtle-battery-list sublist data 5 length data
    ]
  ]
  update-vals
  file-close-all

end

update-vals如上所示。