按周/月中每天的持续时间汇总任务? (POSH)

时间:2018-06-08 18:05:24

标签: powershell grouping pivot-table

我正在从Web服务解析JSON以获取我的任务(使用TimeFlip)。现在,我收回每个任务,发生时间和持续时间,因此数据如下所示:

(taskname, start, durationinSec)
TaskA,"6/5/2018 12:16:36 PM",312
TaskB,"6/5/2018 12:30:36 PM",200
TaskA,"6/6/2018 08:00:00 AM",150
TaskA,"6/6/2018 03:00:00 PM",150
(etc etc)

我想生成一个汇总报告,按天显示哪些任务有多少时间。

虽然数据将持续数周,但我只想做一个每周报告,我可以轻松转录到我们的时间应用程序(因为他们不会给我一个API密钥)。所以我先做where {$_.start -gt (? {$_.start -gt (get-date -Hour 0 -Minute 00 -Second 00).adddays(-7)}之类的事情。

       6/5/2018    6/6/2018
 TaskA 312         300
 TaskB 200      

我该怎么做?我假设是group-object,但不清楚你是如何进行数据透视甚至分组的。

2 个答案:

答案 0 :(得分:5)

以下内容并未输出数据透视表,但执行所需的分组和汇总

$rows = @'
taskname,start,durationinSec
TaskA,"6/5/2018 12:16:36 PM",312
TaskB,"6/5/2018 12:30:36 PM",200
TaskA,"6/6/2018 08:00:00 AM",150
TaskA,"6/6/2018 03:00:00 PM",150
'@ | ConvertFrom-Csv

$rows | Group-Object { (-split $_.start)[0] }, taskname | ForEach-Object {
  $_ | Select-Object @{ n='Date'; e={$_.Values[0]} }, 
                     @{ n='Task'; e={$_.Values[1]} }, 
                     @{ n='Duration'; e={ ($_.Group | Measure-Object durationInSec -Sum).Sum } } 
}

(-split $_.start)[0]按空格分割每个start值,并返回第一个标记([0]),即时间戳的日期部分;例如,6/5/2018返回6/5/2018 12:16:36 PM;将此操作作为脚本块({ ... })传递给Group-Object意味着分组仅按日期进行,而不是按时间进行(除了按taskname进行分组)。

这会产生:

Date     Task  Duration
----     ----  --------
6/5/2018 TaskA      312
6/5/2018 TaskB      200
6/6/2018 TaskA      300

构建类似于pivot-table的输出需要更多的努力,而且它不会很快:

假设$objs包含上面创建的对象($objs = $rows | Group-Object ...)。

# Get all distinct dates.
$dates = $objs | Select-Object -Unique -ExpandProperty Date
# Get all distinct tasks.
$tasks = $objs | Select-Object -Unique -ExpandProperty Task

# Create an ordered hashtable that contains an entry for each task that
# holds a nested hashtable with (empty-for-now) entries for all dates.
$ohtPivot = [ordered] @{}
$tasks | ForEach-Object {
  $ohtDates = [ordered] @{}
  $dates | ForEach-Object { $ohtDates[$_] = $null }
  $ohtPivot[$_] = $ohtDates
}

# Fill the hashtable from the grouped objects with the task- and 
# date-specific durations.
$objs | ForEach-Object { $ohtPivot[$_.Task][$_.Date] = $_.Duration }

# Output the resulting hashtable in pivot-table-like form by transforming
# each entry into a custom object
$ohtPivot.GetEnumerator() | ForEach-Object {
  [pscustomobject] @{ Task = $_.Key } | Add-Member -PassThru -NotePropertyMembers $_.Value
}

以上产量:

Task  6/5/2018  6/6/2018
----  --------  --------
TaskA      312      300
TaskB      200         

答案 1 :(得分:1)

Google搜索Pivot$rotate我发现这个the relative page采用更通用的方式来创建数据透视表。
要转置(交换x,y),您只需更改变量$keep## Q:\Test\2018\06\09\PivotTable.ps1 ## Source https://gist.github.com/andyoakley/1651859 # ############################################################################# # Rotates a vertical set similar to an Excel PivotTable # ############################################################################# $OutputFile = "MyPivot.csv" $data = @' taskname,start,duration TaskA,"6/5/2018 12:16:36 PM",312 TaskB,"6/5/2018 12:30:36 PM",200 TaskA,"6/6/2018 08:00:00 AM",150 TaskA,"6/6/2018 03:00:00 PM",150 '@ | ConvertFrom-Csv |Select-Object taskname, duration, @{n='start';e={($_.start -split ' ')[0]}} # Fields of interest $rotate = "taskname" # Bits along the top $keep = "start" # Those along the side $value = "duration" # What to total #-------------------- No need to change anything below ------------------------ # Creatre variable to store the output $rows = @() # Find the unique "Rotate" [top row of the pivot] values and sort ascending $pivots = $data | select -unique $rotate | foreach { $_.$rotate} | Sort-Object # Step through the original data... # for each of the "Keep" [left hand side] find the Sum of the "Value" for each "Rotate" $data | group $keep | foreach { $group = $_.Group # Create the data row and name it as per the "Keep" $row = new-object psobject $row | add-member NoteProperty $keep $_.Name # Cycle through the unique "Rotate" values and get the sum foreach ($pivot in $pivots) { $row | add-member NoteProperty $pivot ($group | where { $_.$rotate -eq $pivot } | measure -sum $value).Sum } # Add the total to the row $row | add-member NoteProperty Total ($group | measure -sum $value).Sum # Add the row to the collection $rows += $row } # Do something with the pivot rows $rows | Format-Table $rows | Export-Csv $OutputFile -NoTypeInformation
它具有计算行总计

的额外好处
start    TaskA TaskB Total
-----    ----- ----- -----
6/5/2018   312   200   512
6/6/2018   300         300

示例输出:

taskname 6/5/2018 6/6/2018 Total
-------- -------- -------- -----
TaskA         312      300   612
TaskB         200            200

或x / y交换

    class Node:
        def __init__(self, data=None, next_node=None):
            self.data = data
            self.next = next_node

        def __str__(self):
            return str(self.data)


    class LinkedList:
        def __init__(self):
            self.length = 0
            self.head = None

        def print_list(self):
            node = self.head
            while node is not None:
                print(node, end=' ')
                node = node.next
            print('')

        def add_at_head(self, node):
            node.next = self.head
            self.head = node
            self.length += 1

        def remove_node_after(self, node):
            if node.next is not None:
               temp = node.next
               node.next = node.next.next
               temp.next = None


    def remove_odd(l):
        node = l.head
        for i in range(l.length):
            if node % 2 == 0:
                LinkedList.remove_node_after(node)
                node = node.next
            else:
                node = node.next    

    def main():
        my_list = LinkedList()
        my_list.add_at_head(Node(1))
        my_list.add_at_head(Node(2))
        my_list.add_at_head(Node(3))
        remove_odd(my_list)
        my_list.print_list()


    main()