计算 .Net 中 DataGridView 中每个元素的出现频率 Windows 申请表

Count the frequency of each elements in a DataGridView in .Net Windows Application Form

我有一些数据集,我从 csv 文件读取到 DataGridViews 中,我需要绘制一些图表,在其中计算每列上每个不同变量的频率。
我找到了一个 code 来计算数组元素的频率然后打印它们,我尝试在我的数据网格上使用相同的逻辑。
我从只有 2 个值(2.01.0)的列(“SEX”列)开始,但是当我尝试查看计数结果时,我总是得到 1(这意味着这不算什么)。它应该显示在列中找到的最后一个不同值的计数(在我的例子中 2.0 出现了 140 次)。

编辑:我尝试将计数结果附加到文本框,我发现每个循环最终得到 1,而我应该只得到 2 个值(即计数 2.0然后是 1.0)

的计数

我还需要绘制输出,所以我猜我可以使用字典来存储变量名 + 频率。

public void countFreq() //function to count the frequency of each var in a column -not working yet-
        {
            var n = dataGridView1.RowCount;

            var visited = new bool[n];

            // Traverse through array elements and
            // count frequencies
            for (var i = 0; i < n; i++)
            {
                // Skip this element if already processed
                if (visited[i] || dataGridView1.Rows[i].Cells["SEX"].Value
                    == null)
                    continue;
                // Count frequency
                var count = 1;
                for (var j = i + 1; j < n; j++)
                    if (dataGridView1.Rows[i].Cells["SEX"].Value == dataGridView1.Rows[j].Cells["SEX"].Value)
                    {
                        visited[j] = true;
                        count++;
                    }

                textFile.Text += count.ToString(); //for testing purposes I used a textfield to print the last count value
            }
        }

我知道对于值是明确的列,我可以在我的数据网格行上循环并使用计数方法(我这样做了)但是对于我的大多数数据我并没有明确知道每行中的值所以我需要找到一种方法来做到这一点。

我不确定这是否是您要找的。此外,下面的代码循环遍历网格中的行,但是,如果网格有数据源,我建议循环遍历该集合而不是网格行。

下面是一个采用列索引和 returns 一个 Dictionary<string, int> 的方法。一个简单的循环遍历给定列中的每个单元格,如果单元格的 Value 不在字典中,我们将添加它。如果单元格值已经在字典中,将简单地增加其 int Value。循环结束后,返回字典。像……

private Dictionary<string, int> GetCountOfValues(string columnName) {
  string curKey = "";
  Dictionary<string, int> valuesAndCounts = new Dictionary<string, int>();
  foreach (DataGridViewRow row in dataGridView1.Rows) {
    if (!row.IsNewRow) {
      if (row.Cells[columnName].Value != null) {
        curKey = row.Cells[columnName].Value.ToString();
        if (valuesAndCounts.ContainsKey(curKey)) {
          valuesAndCounts[curKey]++;
        }
        else {
          valuesAndCounts.Add(curKey, 1);
        }
      }
    }
  }
  return valuesAndCounts;
}

用法可能类似于……

Dictionary<string, int> column0Counts = GetCountOfValues("Col0");
Dictionary<string, int> column1Counts = GetCountOfValues("Date");

您真的应该将 CSV 数据加载到数据表中,然后查询该数据

var dt = SomeFunctionThatReadsCsvIntoDatatable(..);

yourDataGridView.DataSource = dt;

然后通过使用 linq 对数据表进行分组来简单地回答您的查询;

(yourDataGridView.DataSource as DataTable).Rows
    .Cast<DataRow>()
    .GroupBy(r => r["someColumn"])
    .Select(g => new { K = g.Key, C = g.Count() });
    
  • "someColumn" 将是 "SEX"
  • K 最终会作为一个 object 保存数据的任何类型 ` - 很难从发布的信息中判断您是否刚刚将 csv 作为字符串或者它们是否是双打,日期等

如果您想对所有列执行此操作,最简单的方法可能是在数据表 Columns 集合的循环中执行此操作。 DataColumn.ColumnName 提供“someColumn”