I am new to Deedle. I searched everywhere looking for examples that can help me to complete the following task:
Index data frame using multiple columns (3 in the example - Date, ID and Title)
Add numeric columns in multiple data frames together (Sales column in the example)
Group and add together sales occurred on the same day
My current approach is given below. First of all - it does not work because of the missing values and I don't know how to handle them easily while adding data frames. Second - I wonder if there is a better more elegant way to do it.
// Remove unused columns
var df = dfRaw.Columns[new[] { "Date", "ID", "Title", "Sales" }];
// Index data frame using 3 columns
var dfIndexed = df.IndexRowsUsing(r => Tuple.Create(r.GetAs<DateTime>("Date"), r.GetAs<string>("ID"), r.GetAs<string>("Title")) );
// Remove indexed columns
dfIndexed.DropColumn("Date");
dfIndexed.DropColumn("ID");
dfIndexed.DropColumn("Title");
// Add data frames. Does not work as it will add only
// keys existing in both data frames
dfTotal += dfIndexed
Table 1
Date,ID,Title,Sales,Market
2014-03-01,ID1,Title1,1,US
2014-03-01,ID1,Title1,2,CA
2014-03-03,ID2,Title2,3,CA
Table 2
Date,ID,Title,Sales,Market
2014-03-02,ID1,Title1,2,US
2014-03-03,ID2,Title2,2,CA
Expected Results
Date,ID,Title,Sales
2014-03-01,ID1,Title1,3
2014-03-02,ID1,Title1,2
2014-03-03,ID2,Title2,5
I think that your approach with using tuples makes sense.
It is a bit unfortunate that there is no easy way to specify default values when adding!
The easiest solution I can think of is to realign both series to the same set of keys and use fill operation to provide defaults. Using simple series as an example, something like this should do the trick:
var allKeys = seris1.Keys.Union(series2.Keys);
var aligned1 = series1.Realign(allKeys).FillMissing(0.0);
var aligned2 = series2.Realign(allKeys).FillMissing(0.0);
var res = aligned1 + aligned2;
Related
I have two DataGridView in the main form and the first one displays data from SAP and another displays data from Vertica DB, the FM I'm using is RFC_READ_TABLE, but there's en exception when calling this FM, which is, if there are too many columns in target table, SAP connector will returns an DATA_BUFFER_EXCEED exception, is there any other FMs or ways to retrieving data from SAP without exception?
I figured out a solution, is about split fields into several arrays and store each parts data into a datatable, then merge datatables, but I'm afraid it will cost a lot of time if the row count is too large.
screenshot of the program
here comes my codes:
RfcDestination destination = RfcDestinationManager.GetDestination(cmbAsset.Text);
readTable = destination.Repository.CreateFunction("RFC_READ_TABLE");
/*
* RFC_READ_TABLE will only extract data up to 512 chars per row.
* If you load more data, you will get an DATA_BUFFER_EXCEEDED exception.
*/
readTable.SetValue("query_table", table);
readTable.SetValue("delimiter", "~");//Assigns the given string value to the element specified by the given name after converting it appropriately.
if (tbRowCount.Text.Trim() != string.Empty) readTable.SetValue("rowcount", tbRowCount.Text);
t = readTable.GetTable("DATA");
t.Clear();//Removes all rows from this table.
t = readTable.GetTable("FIELDS");
t.Clear();
if (selectedCols.Trim() != "" )
{
string[] field_names = selectedCols.Split(",".ToCharArray());
if (field_names.Length > 0)
{
t.Append(field_names.Length);
int i = 0;
foreach (string n in field_names)
{
t.CurrentIndex = i++;
t.SetValue(0, n);
}
}
}
t = readTable.GetTable("OPTIONS");
t.Clear();
t.Append(1);//Adds the specified number of rows to this table.
t.CurrentIndex = 0;
t.SetValue(0, filter);//Assigns the given string value to the element specified by the given index after converting it appropriately.
try
{
readTable.Invoke(destination);
}
catch (Exception e)
{
}
first of all you should use BBP_READ_TABLE if it is available in your system. This one is better for much reasons. But that is not the point of your question. In RFC_READ_TABLE you have two Imports ROWCOUNT and ROWSKIPS. You have to use them.
I would recommend you a rowcount between 30.000 and 60.000. So you have to execute the RFC several times and each time you increment your ROWSKIPS. First loop: ROWCOUNT=30000 AND ROWSKIPS = 0, Second Loop: ROWCOUNT=30000 AND ROWSKIPS=30000 and so on...
Also be careful of float-fields when using the old RFC_READ_TABLE. There is one in table LIPS. This RFC has problems with them.
Use transaction
BAPI
press filter and set to all.
Under Logistics execution you will find deliveries.
The detail screen shows the function name.
Test them directly to find one thats suits then call that function instead of RFC_read_tab.
example:
BAPI_LIKP_GET_LIST_MSG
Another possibility is to have an ABAP RFC function developped to get your datas (with the advantage that you can get a structured / multi table response in one call, and the disadvantage that this is not a standard function / BAPI)
I am going to ask a very basic question and probably a repeated one but I have a bit different situation.
I want to use "in" operator in Linq.
I have to get all the rows from table which has Id provided
by my array and returns the row if it has. How can I do it.
My array has
var aa="1091","1092","1093" and so on.
and my table uses these Ids as Primary keys
.I have to get all the rows whose Id is contained in the array and I do not want to use S.P.
You can use Enumerable.Contains,
var aa = new string[3] { "1091", "1092", "1093" };
var res = yourDataSource.Where(c => aa.Contains(c.ID));
IN statements are created by using Contains in your Where call. Assuming you use integers as IDs, you could write something like this:
var myArray=new[]{1091,1092,1094};
var myEntities=from entity in myTable
where myArray.Contains(entity.ID)
select entity;
This one is probably a little stupid, but I really need it. I have document with 5 tables each table has a heading. heading is a regular text with no special styling, nothing. I need to extract data from those tables + plus header.
Currently, using MS interop I was able to iterate through each cell of each table using something like this:
app.Tables[1].Cell(2, 2).Range.Text;
But now I'm struggling on trying to figure out how to get the text right above the table.
Here's a screenshot:
For the first table I need to get "I NEED THIS TEXT" and for secnd table i need to get: "And this one also please"
So, basically I need last paragraph before each table. Any suggestions on how to do this?
Mellamokb in his answer gave me a hint and a good example of how to search in paragraphs. While implementing his solution I came across function "Previous" that does exactly what we need. Here's how to use it:
wd.Tables[1].Cell(1, 1).Range.Previous(WdUnits.wdParagraph, 2).Text;
Previous accepts two parameters. First - Unit you want to find from this list: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.wdunits.aspx
and second parameter is how many units you want to count back. In my case 2 worked. It looked like it should be because it is right before the table, but with one, I got strange special character: ♀ which looks like female indicator.
You might try something along the lines of this. I compare the paragraphs to the first cell of the table, and when there's a match, grab the previous paragraph as the table header. Of course this only works if the first cell of the table contains a unique paragraph that would not be found in another place in the document:
var tIndex = 1;
var tCount = oDoc.Tables.Count;
var tblData = oDoc.Tables[tIndex].Cell(1, 1).Range.Text;
var pCount = oDoc.Paragraphs.Count;
var prevPara = "";
for (var i = 1; i <= pCount; i++) {
var para = oDoc.Paragraphs[i];
var paraData = para.Range.Text;
if (paraData == tblData) {
// this paragraph is at the beginning of the table, so grab previous paragraph
Console.WriteLine("Header: " + prevPara);
tIndex++;
if (tIndex <= tCount)
tblData = oDoc.Tables[tIndex].Cell(1, 1).Range.Text;
else
break;
}
prevPara = paraData;
}
Sample Output:
Header: I NEED THIS TEXT
Header: AND THIS ONE also please
Hello I am failry new to silverlight and C# and have a program that utilizes the RIA techinique of using data. I am having problems with selecting a single column from my datasource. I am trying to use the value of that column to populate a single series in my chart.
On my UI I have a Grid and a bar chart.
I am able to populate my Grid by using:
DomainContext ctx = new DomainContext();
ListingGrid.ItemsSource = ctx.v_IQ_Flashes;
ctx.Load(ctx.Get_Table1());
That populates my datagrid with all(*) fields from my table Table1
Now I want to populate a single series on my chart with just one column from that chart.
Using the following code yeilds a return value of 0 (which is incorrect). What am I doing wrong?
var slot = ctx.v_IQ_Flashes.Where(e => e.Year == t_year).Select(e => e.Win );
var sum_ret_slot = slot.Sum();
decimal sum_slot = sum_ret_slot.Value;
Note that all values, (Slot, sum_ret_slot, sum_slot) are all 0. I used the debugger to verify that these are indeed being called and that their values are all 0.
It seems to me that you aren't actually getting anything from your Where clause.
Does removing the where clause cause it to work, it so I would evaluate that and determine why that isn't matching any records.
I agree with msarchet - check the value of your t_year variable - are there any rows which actually match your Where predicate?
Do you get results if you change the code to:
var slot = ctx.v_IQ_Flashes.Select(e => e.Win );
var sum_ret_slot = slot.Sum();
decimal sum_slot = sum_ret_slot.Value;
Or do you get results if you change the code to:
var slot = ctx.v_IQ_Flashes.Where(e => e.Year == 2010).Select(e => e.Win );
var sum_ret_slot = slot.Sum();
decimal sum_slot = sum_ret_slot.Value;
Where do you add code of sum_slot getting?
If you do it consequentially with loading, zero results are right cause ctx.Load(ctx.Get_Table1()) is async operation and if next your step is filter, data is not loaded yet.
I think, first way to make this code right - add filter to callback
ctx.Load(ctx.Get_Table1(), ()=>{//get sum_slot }, null);
Second way - apply filter to query:
ctx.Load(ctx.Get_Table1().Where(e => e.Year == t_year)) - context will load filtered items.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to split an array into a group of n elements each?
I believe I oversimplified this question so I am editing it a bit. From within a .NET 3.5 console application I have a SortedList string,string that will contain an unknown number of key/value pairs. I will get this collection by reading in rows from a table within a Microsoft Word document. The user will then be able to add additional items into this collection. Once the user has finished adding to the collection I then need to write the collection back to a new Microsoft Word document. The difficulty is that the items must be written back to the document in alphabetical order to a multicolumn table, first down the left side of the table and then down the right side of the table and since the output will likely be spread across multiple pages I need to also keep the order across multiple pages. So the first table on the first page may contain A through C on the left side of the table and C through F on the right side of the table then if the table exceeds the page a new table is needed. The new table may contain F through I and the right side L through O.Since the table will likely span multiple pages and I know the maximum number of rows per table per page I can do the math to determine how many tables I will need overall. This image is representative of the output:
For the sake of brevity if a output table can contain a maximum of 7 rows per page and 2 items per row and I have 28 items then I will need to write the output to 2 tables but of course I won't really know how many tables I will need until I read in the data so I can't simply hardcode the number of output tables.
What is the best way to take my SortedList and split it out into n collections in order to create the table structure described?
It is not necessary to split the list (if the only purpose is to write items in a table).
You can just iterate through the list and write row breaks in appropriate places.
for (int i = 0; i < sortedList.Count; i++)
{
if (i % 3 == 0)
{
Console.Write("|"); // write beginning of the row
}
Console.Write(sortedList[i].ToString().PadRight(10)); // write cell
Console.Write("|"); // write cell divider
if (i % 3 == 2)
{
Console.WriteLine() // write end of the row
}
}
// optional: write empty cells if sortedList.Count % 3 != 0
// optional: write end of the row if sortedList.Count % 3 != 2
You should extend your question by specifying what is the output of your script. If you want to write a table to the console, the above solution is probably the best. However, if you are using rich user interface (such as WinForms or ASP.NET), you should use built-in tools and controls to display data in table.
I played with LINQ a little bit and came up with this solution. It creates some kind of tree structure based on the "input parameters" (rowsPerPage and columnsPerPage). The columns on the last page could not have the same size (the code can be easily fixed if it is a problem).
SortedList<string, string> sortedList ... // input sortedList
int rowsPerPage = 7;
int columnsPerPage = 2;
var result = from col in
(from i in sortedList.Select((item, index) => new { Item = item, Index = index })
group i by (i.Index / rowsPerPage) into g
select new { ColumnNumber = g.Key, Items = g })
group col by (col.ColumnNumber / columnsPerPage) into page
select new { PageNumber = page.Key, Columns = page };
foreach (var page in result)
{
Console.WriteLine("Page no. {0}", page.PageNumber);
foreach (var col in page.Columns)
{
Console.WriteLine("\tColumn no. {0}", col.ColumnNumber);
foreach (var item in col.Items)
{
Console.WriteLine("\t\tItem key: {0}, value: {1}", item.Item.Key, item.Item.Value);
}
}
}