这是我在这里的第一个问题。我是一名气象学家并且有一些编码经验,尽管它远非专业教学。基本上我所拥有的是来自气象站的.csv文件,它给我的数据太详细了。 (65.66度和类似的值)我想要做的是通过脚本文件自动化一种方式,该文件将访问.csv文件并删除过于详细的值。 (将温度从65.66提高到66(对于任何高于.5以及向下用于下方),或者使用相同的舍入规则进行压力(29.8889)并使其成为(29.89)。这是否可以实现?如果是这样,我应该怎么做呢。再次请记住,我对批处理文件的编码技巧并不是最强的。
非常感谢任何帮助。
谢谢,
答案 0 :(得分:2)
我同意上述评论。批量数学仅限于整数,并且不适合您想要的操作。
我会使用PowerShell。除了轻松处理浮点数学之外,它还具有用于对CSV数据(以及XML和其他类型的结构化数据)进行客观化的内置方法。获取weather.csv
中包含的以下假设CSV数据:
date,time,temp,pressure,wx
20160525,12:30,65.66,30.1288,GHCND:US1TNWS0001
20160525,13:00,67.42,30.3942,GHCND:US1TNWS0001
20160525,13:30,68.92,31.0187,GHCND:US1TNWS0001
20160525,14:00,70.23,30.4523,GHCND:US1TNWS0001
20160525,14:30,70.85,29.8889,GHCND:US1TNWS0001
20160525,15:00,69.87,28.7384,GHCND:US1TNWS0001
您要做的第一件事是将数据作为对象导入(使用import-csv
),然后根据需要舍入数字 - temp舍入为整数,压力舍入为2的十进制精度地方。四舍五入很容易。只需将数据重新整理为整数。它会自动舍入。如果您调用.NET [math]::round()
方法,那么舍入压力列也非常简单。
# grab CSV data as a hierarchical object
$csv = import-csv weather.csv
# for each row of the CSV data...
$csv | foreach-object {
# recast the "temp" property as an integer
$_.temp = [int]$_.temp
# round the "pressure" property to a precision of 2 decimal places
$_.pressure = [math]::round($_.pressure, 2)
}
现在假装您要显示“日期”= 20160525和“时间”= 14:30的温度,气压和气象站名称。
$row = $csv | where-object { ($_.date -eq 20160525) -and ($_.time -eq "14:30") }
$row | select-object pressure,temp,wx | format-table
假设“压力”开始时的值为29.8889,而“temp”的值为70.85,则输出为:
pressure temp wx
-------- ---- --
29.89 71 GHCND:US1TNWS0001
如果CSV数据有多行具有相同的日期和时间值(可能来自不同气象站的测量值),那么该表将显示多行。
如果您想将其导出到新的csv文件,只需将format-table
cmdlet替换为export-csv destination.csv
$row | select-object pressure,temp,wx | export-csv outfile.csv
作为衬衫上的口袋方便,对吗?
现在,假装您想要显示人类可读的电台名称而不是NOAA的名称。制作哈希表。
$stations = @{
"GHCND:US1TNWS0001" = "GRAY 1.5 E TN US"
"GHCND:US1TNWS0003" = "GRAY 1.9 SSE TN US"
"GHCND:US1TNWS0016" = "GRAY 1.3 S TN US"
"GHCND:US1TNWS0018" = "JOHNSON CITY 5.9 NW TN US"
}
现在您可以为“行”对象添加“station”属性。
$row = $row | select *,"station"
$row.station = $stations[$row.wx]
现在如果你这样做了:
$row | select-object pressure,temp,station | format-table
您的控制台显示:
pressure temp station
-------- ---- -------
29.89 71 GRAY 1.5 E TN US
要获得额外的功劳,请说您要将此行数据导出为JSON(对于网页或其他内容)。这有点复杂,但并非不可能。
add-type -AssemblyName System.Web.Extensions
$JSON = new-object Web.Script.Serialization.JavaScriptSerializer
# convert $row from a PSCustomObject to a more generic hash table
$obj = @{}
# the % sign in the next line is shorthand for "foreach-object"
$row.psobject.properties | %{
$obj[$_.Name] = $_.Value
}
# Now, stringify the row and display the result
$JSON.Serialize($obj)
该输出应与此类似:
{"station":"GRAY 1.5 E TN US","wx":"GHCND:US1TNWS0001","temp":71,"date":"201605
25","pressure":29.89,"time":"14:30"}
...您可以使用>
将其重定向到.json文件,或将其传递到out-file
cmdlet。
答案 1 :(得分:2)
<强> Excel中强>
Say you have 66.667 in cell B12. Set the formula in C13 to...
"=ROUND(B12,0)" to round to integer
"=ROUND(B12,1)" to round to one decimal place
As you copy and past, Excel will attempt to intelligently update the formulas for you.
<强>的Python 强>
import pandas as pd
from StringIO import StringIO
import numpy as np
# load csv file to memory. Name your columns "using names=[]"
df = pd.read_csv(StringIO("C:/temp/weather.csv"), names=["city", "temperature", "date"])
df["temperature"].apply(np.round) #you just rounded the temperature column
pd.to_csv('newfile.csv') # export to a new csv file
pd.to_xls('newfile.xls') # or export to an excel file instead
DOS批次 这个批处理脚本要困难得多。我不会写整个程序,因为它不是一个很好的解决方案。但是,我将在本文的底部给你一个DOS批处理代码的味道。与使用Python或Excel相比,它非常复杂。
这是DOS代码的粗略草图。因为我不推荐这种方法,所以我没有花时间调试这段代码。
setlocal ENABLEDELAYEDEXPANSION
:: prep our new file for output. Let's write the header row.
echo col1, col2, col3 >newfile.csv
:: read the existing text file line by line
:: since it is csv, we will parse on comma
:: skip lines starting with semi-colon
FOR /F "eol=; tokens=2,3* delims=, " %%i in (input_file.txt) do (
set col1=%%I, set col2=%%J, set col3=%%K
:: truncate col2 to 1 decimal place
for /f "tokens=2 delims==." %%A in ("col2") do (
set integer=%%A
set "decimal=%%B
set decimal=%decimal:~0,1%
:: or, you can use an if statement to round up or down
:: Now, put the integer and decimal together again and
:: redefine the value for col2.
set col2=%integer%.%decimal%
:: write output to a new csv file
:: > and >> can redirect output from console to text file
:: >newfile.csv will overwrite file.csv. We don't want
:: that, since we are in a loop.
:: >>newfile.csv will append to file.csv, perfect!
echo col1, col2, col3 >>newfile.csv
)
)
:: open csv file in default application
start myfile.csv