flutter 按元素的列表的 dart 和列表

n9vozmp4  于 2023-02-13  发布在  Flutter
关注(0)|答案(4)|浏览(153)

我尝试通过索引将列表中的所有元素相加并求平均值:

List<List<double>> data = [[1.0, 2.0, 3.0], [2.0, 3.0, 5.0], [8.0, 7.0, 2.0]]

结果应该是一个双精度数列表,每个双精度数相加,然后除以上述数据的总长度:

[11.0, 12.0, 10.0] // divide these by 3
[3.67, 4.0, 3.33] // should be the result

最好的方法是什么?这在我的flutter应用程序中花费了太长的时间(实际的数据列表包含60个列表,每个列表包含2000个double),是的,我还Assert每个列表的长度是相等的,并且不为空或具有意外的数据类型。

8mmmxcuj

8mmmxcuj1#

我真的不知道你需要什么样的速度。
试试这个方法,看看它是否适用于你的数据集。也许你的方法更快!

void main() {
  List<List<double>> data = [[1.0, 2.0, 3.0], [2.0, 3.0, 5.0], [8.0, 7.0, 2.0]];
  List<double> dataSum = List<double>();
  
  // original data
  print(data);
  
  for (var item in data){
    dataSum.add(item.fold(0, (p, c) => p + c) / item.length);
  }
  
  // output
  print(dataSum);
}

**重要提示:**无论如何,如果您要及时完成一项大型任务,您可以将async函数与Future配合使用,以防止应用程序挂起,并且不会因为长时间等待而受到影响。

  • 更新:OP评论后 *

这段代码应该会给予你你所期望的结果。

void main() {
  List<List<double>> data = [[1.0, 2.0, 3.0], [2.0, 3.0, 5.0], [8.0, 7.0, 2.0]];

  int numLists = data.length;
  int numElements = data[0].length;
  double sum;
  List<double> dataSum = List<double>();
  
  for(var i = 0; i < numElements; i++ ) { 
    sum = 0.0;
    for(var j = 0; j < numLists; j++ ) { 
      sum += data[j][i]; //inverted indexes
    }
    dataSum.add(sum/numLists);
  }
  
  // output
  print(dataSum);
}
hfwmuf9z

hfwmuf9z2#

我对矩阵NxM的贡献,我修改了您的数据,以获得更通用的解决方案:

extension chesu<T> on List<List<T>> {
  List<List<T>> transpose() {
    final rowNum = this.length;
    final colNum = this[0].length;
    var list = List<List<T>>.generate(colNum, (i) => List<T>());

    if (rowNum == 0 || colNum == 0) return null;

    for (var r = 0; r < rowNum; r++)
      for (var c = 0; c < colNum; c++) list[c].add(this[r][c]);
    return list;
  }
}

main(List<String> args) {
  final data = [[1.0, 2.0, 3.0, 4.0], [2.0, 3.0, 5.0, 8.0], [6.0, 7.0, 7.0, 9.0]];
  print(data.transpose().map((e) => e.reduce((v, e) => v+e)).map((e) => e/3));
}

结果:

(3.0, 4.0, 5.0, 7.0)

有一个名为scidart的新包,它包含了一些有趣的函数,比如transpose,它试图从Python中模拟numpy

    • 更新1:使用大数据**
    • 更新2:**我犯了一个愚蠢的错误与sum()extension是固定的,现在,对不起。
import 'dart:math';

extension on List<List<double>> {
  List<List<double>> transpose() {
    final rowNum = this.length;
    final colNum = this[0].length;
    var list = List<List<double>>.generate(colNum, (i) => List<double>());

    if (rowNum == 0 || colNum == 0) return null;

    for (var r = 0; r < rowNum; r++)
      for (var c = 0; c < colNum; c++) list[c].add(this[r][c]);
    return list;
  }
  
  List<double> sum() => this.map((l) => l.reduce((v, e) => v+e)).toList();
}

class Stats {
  List<List<double>> _data;
  int _rows, _cols;
  List<double> _sum, _avg;

  Stats(List<List<double>> data) {
    _data = data.transpose();
    _rows = _data.length;
    _cols = _data[0].length;
  }

  int get rows => _rows;
  int get cols => _cols;

  List<double> get sum {
    if ([0, null].contains(_sum)) _sum = _data.sum();
    return _sum;
  }

  List<double> get avg {
    if ([0, null].contains(_avg)) _avg = sum.map((e) => e / _cols).toList();
    return _avg;
  }
}

main(List<String> args) {
  // final data = [[1.0, 2.0, 3.0, 4.0], [2.0, 3.0, 5.0, 8.0], [6.0, 7.0, 7.0, 9.0]];
  // final data = [[1.0, 2.0, 3.0], [2.0, 3.0, 5.0], [8.0, 7.0, 2.0]];
  final data = List<List<double>>.generate(60, (i) => List<double>.generate(2000, (j) => Random().nextDouble()*30));
  print('Creating big data...');
  final stats = Stats(data);

  final stopwatch = Stopwatch()..start();
  print('Calculating statistics...');
  print('Sum: ${stats.sum.take(5)}');
  print('Average: ${stats.avg.take(5)}');
  stopwatch.stop();
  print('\nJob finished at ${stopwatch.elapsedMilliseconds/1000} seconds.');
}

结果:

Creating big data...
Calculating statistics...
Sum: (928.8075263386316, 934.3418807027017, 815.2172548417801, 833.6855783984151, 828.1013228547513)
Average: (15.480125438977193, 15.572364678378362, 13.586954247363002, 13.894759639973586, 13.801688714245854)

Job finished at 0.024 seconds.
jaxagkaj

jaxagkaj3#

对于列表的操作,你必须迭代它的项(for,map,forEach ...等等),这将花费时间(取决于列表的长度),所以我猜你必须做一些基准测试。
试试这个

List<double> sum = [];
  List<double> average = [];

  sum = data.reduce((a, b) {
    List<double> list = [];
    for (int i = 0; i < b.length; i++) {
      list.add(a[i] + b[i]);
    }
    return list;
  });

  average = sum.map((e) => e / 3).toList();

  print(sum);
  print(average);
8zzbczxx

8zzbczxx4#

var res = <double>[];
final innerListSize = data[0].length;
for (int i = 0; i < innerListSize; i++) {
  res.add(data.map((e) => e[i]).average);
}

相关问题